[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: unified methods
- From: "Jay Carlson" <nop@...>
- Date: Wed, 28 Nov 2001 23:32:50 -0500
"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