[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Let's talk about __call
- From: Adrián Pérez de Castro <aperez@...>
- Date: Fri, 22 Jul 2016 11:41:05 +0300
Quoting Dirk Laurie (2016-07-22 10:48:09)
> 2016-07-22 4:57 GMT+02:00 Patrick Donnelly <batrick@batbytes.com>:
> > For some slightly early "It's Friday" discussion, what do you use the
> > __call metamethod for? Discuss your favorite hacks, strange problems
> > solved, code golf hole-in-ones, etc.
> >
> > To get discussion started, I'll leave this here:
> >
> > t = setmetatable({}, {__index = table, __call = function(t, method)
> > return function(...) t[method](t, ...) end end}) -- create a method
> > binding
> > string.gsub("foo", ".", t "insert")
> > for k,v in pairs(t) do print(k,v) end --> 1 f \n 2 o \n 3 o \n
>
> I use a minimal object-oriented paradigm in which the method
> table is also the __index and the constructor.
>
> local init = function(class,object)
> setmetatable(object,class)
> return object
> end
>
> local Class = function(methods,typename)
> methods.__index = methods
> methods.type = function() return typename end
> return setmetatable(methods,{__call = init})
> end
>
> I don't package these in a module. They are clearly visible to
> whoever reads the listing.
>
> After that, e.g.
>
> Data = Class({},'data')
> data = Data{}
>
> I've been using this for so long that I have forgotten where I got it.
> Probably from PiL.
I do something similar to allow “instantiation” of objects with the __call
metamethod, to have Python-like syntax. I do it manually every time, without
having any helper functions. It goes like this.
local Point = {}
Point.__index = Point
setmetatable(Point, { __call = function (self, x, y)
return setmetatable({ x=x, y=y }, self)
end })
-- Metamethods can be attached directly
function Point:__tostring()
return string.format("Point(%d, %d)", self.x, self.y)
end
function Point:translate(dx, dy)
self.x, self.y = self.x + dx, self.y + dy
return self
end
...and so on. Probably I do not use helper functions because I just see this
as “needed boilerplate”, and also because it's not too long it feels right to
write this explicitly. I cannot remember from where I got this... it could
have been as well that my code slowly morphed over time to arrive to this
pattern, which has been unchanged for the last 5 years at least.
Sometimes I have used __call for other purposes, but not very often. Most of
the time to return custom iterators:
local obj = Cls() -- This has a __call metamethod...
for x in obj() do -- ...which returns a coroutine.
print(x)
end
Cheers,
--
☛ Adrián
Attachment:
signature.asc
Description: signature