lua-users home
lua-l archive

Re: unified methods

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


"John Belmonte" <jvb@prairienet.org> writes:
> Jay Carlson wrote:
>
> > Look, I haven't made up my mind yet about unified methods. They
> > offer a lot of nice features that seem useful in day-to-day
> > programming. But it's a significant enough change that I need to
> > think about it, a lot---because it *is* an interesting and thoughtful
> > proposal.
>
> Actually unified methods doesn't offer many features at all. It's just
> taking Lua's internal tag method system an exposing it as tables (this is
> why Edgar was shocked by your comment about everything-as-tables). Lua's
> tag method interface is spotty and hard to follow, so unified methods just
> make you think you're getting a whole lot more. It's an illusion.
Although this post has been overtaken by events, I thought it might be cool
to do this in base Lua 4.0. Another hour of my life wasted by tag
methods---help help it's SO MUCH FUN TO WRITE THIS STUFF
Jay
---------------------
dofile("tag.lua")
hellotag = Tag.new()
function hellotag.gettable(table, index)
 return "Hello from "..tostring(index)
end
print("hellotag.gettable", hellotag.gettable)
-- had to rename this event from "function" to "func"...
function hellotag.func(...)
 print("hello, world!")
end
hello = {}
hellotag:applyTo(hello)
hello()
print("hello.Jay", hello.Jay)
-- You can get a Tag from any value you're got lying around:
hellotag2 = Tag.fromValue(hello)
print("hellotag == hellotag2", hellotag == hellotag2)
-- Or for existing types:
numtag = Tag.fromValue(1)
numtag2 = Tag.fromValue(2)
print("numtag == numtag2", numtag == numtag2)
----------------------------------------------------------------------
-- tag.lua
if Tag then return end
local Public, Private = {}, {}
Tag = Public
Private.tagtag = newtag()
Private.tagnum_to_Tag = {}
function Public.new()
 local tagnum = newtag()
 local t = {tag=tagnum}
 settag(t, %Private.tagtag)
 %Private.tagnum_to_Tag[tagnum]=t
 return t
end
function Private.makeOld(tagnum)
 local t = {tag=tagnum}
 settag(t, %Private.tagtag)
 %Private.tagnum_to_Tag[tagnum]=t
 return t
end
function Public.fromTagNumber(n)
 local tag = %Private.tagnum_to_Tag[n]
 if not tag then
 tag = %Private.makeOld(n)
 end
 return tag
end
function Public.fromValue(v)
 local tagnum = tag(v)
 return %Public.fromTagNumber(tagnum)
end
Private.event_set = {
 add="add", sub="sub", mul="mul", div="div", pow="pow",
 umm="umm",
 lt="lt",
 concat="concat",
 index="index",
 getglobal="getglobal", setglobal="setglobal",
 gettable="gettable", settable="settable",
 func="function" -- because you can't say foo.function = bar
}
function Private:applyTo_method(v)
 settag(v, self.tag)
end
Private.method_table = {applyTo=Private.applyTo_method}
function Private.gettable_handler(table, index)
 local method = %Private.method_table[index]
 if method then return method end
 local event = %Private.event_set[index]
 if event then
 return gettagmethod(rawget(table, "tag"), event)
 else
 return rawget(table, index)
 end
end
function Private.settable_handler(table, index, value)
 local event = %Private.event_set[index]
 if event then
 settagmethod(rawget(table, "tag"), event, value)
 else
 rawset(table, index, value)
 end
end
settagmethod(Private.tagtag, "gettable", Private.gettable_handler)
settagmethod(Private.tagtag, "settable", Private.settable_handler)
function Public:copyMethodsFrom(tag)
 for i,v in %Private.event_set do
 settagmethod(self.tag, v, tag[v])
 end
end

AltStyle によって変換されたページ (->オリジナル) /