lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Soni L. once stated:
> Remember there were multiple threads about adding semantic meaning to 
> specific string objects, etc?
> 
> For example, say you want a date string, that acts like a string, but 
> has added methods: (using io.write here to indicate its stringness)
> 
> local date = Date.new("1/1/1970")
> io.write(date, "\n") --> 1970-01-01-T00:00:00.000+00:00
> date = date:add("10y")
> io.write(date, "\n") --> 1980-01-01-T00:00:00.000+00:00
> io.write(date:as("ISO 8601"), "\n") --> 1980-01-01-T00:00:00.000+00:00
> local t = {}
> t[date] = true
> io.write(next(t), "\n") --> 1980-01-01-T00:00:00.000+00:00
> 
> The way to do this is to do this:

  I see (I think) what you are trying to do, but if I were to implement
this, I would make a separate date "type" and write a __tostring() method
for it.  So the only difference I would see is:

	local date = Date.new("January 8, 1969")
	io.write(tostring(date),"\n")
	date = date + "10y" -- I mean, if you have a new type, go all out!
	io.write(tostring(date),"\n")

> local t = setmetatable({}, {__mode = "k"})
> function Date.new(date, format)
>   local processedDate = getDateString(date, format)
>   t[processedDate] = {date_metadata_here}
>   return processedDate
> end
> function string:as(format)
>   if t[self] then
>     return convertDate(self, format)
>   else
>     error("Not a date object")
>   end
> end

  Now I'm confused.  It appears as if Date.new() returns an actual string as
opposed to a userdata or table and that you have monkey patched the string
metatable to include the add() and as() methods.  If that is the case, then
that's shortsighted.  I use your Date module, and Dirk's (hypothetical)
string encoding module, where you can do:

	io.write(header:as("quoted-printable"),value:as("base-64"),"\n")

And well ... your :as() and Dirk's (hypothetical) :as() don't mix.  The
issue here is that strings all share a single metatable, so for your method
to work, that would have to change (and I do believe there was a discussion
about that (ah yes, http://lua-users.org/lists/lua-l/2015-05/msg00021.html).

> However, this causes conflicts and interning issues and stuff. So let's 
> look at proposals to solve this:
> 
> There is a metamethod proposal that would make this better. Not perfect, 
> but way better. It's __key. It would provide a general-purpose solution 
> to this age-old problem:
> 
> local mt = {
>   __index = {}
>   __key = function(self) return self.date end
> }
> function Date.new(date, format)
>   local processedDate = getDateString(date, format)
>   return setmetatable({date=processedDate}, mt)
> end
> function mt.__index:as(format)
>   return convertDate(self, format)
> end

  I'm afraid I don't see how this is supposed to work.  From the other
thread, 

	io.write(date)

won't trigger the __key metamethod because it's not being used as a key. 
Unless you are now changing the semantics of __key.  Perhaps a line-by-line
running commentary of not only the definition of your example, but use as
well is required.  

  -spc (Or here's a radical idea---try implementing it!)