[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: More on environments and objects
- From: Rici Lake <lua@...>
- Date: Sun, 28 Aug 2005 00:21:05 -0500
On 27-Aug-05, at 10:44 PM, Chris Marrin wrote:
If I found this acceptable:
local a = SFBoolean(true)
if a == SFTrue then...
then all would be well. But I don't. Even these two:
if a == true then...
if a:valueOf() then...
which both work after I made my "fix" to __eq, is not acceptable to
me. It has to be:
if a then...
so I will have to make the change to the VM.
Now you're just being stubborn :)
If you use Lua 5.1, you can attach a metatable to the boolean type. It
only has two instances, true and false. So SFBoolean can be the
identity operator. The only limitation that this brings is that you can
only have a single instance of the false object. I don't see this as
problematic.
All non-false objects (except, of course, nil) will satisfy
if a then ...
So there is absolutely no problem with having multiple true objects.
Now, if you wanted to implement a non-deterministic language, this
wouldn't work:
local a = SFBoolean("maybe")
if a then -- maybe it jumps, maybe it doesn't :)
...
end
There are applications for this sort of thing but I have a hunch that
yours isn't one of them.
If I'm missing something obvious, feel free to continue this thread...
By the way, I checked the 5.1work6 code. It still insists that objects
have the same (lua) type in order to be compared, so it won't do what
you want. It would be easy-ish to change the check to "same metamethod"
with a little jiggling.
Current lessthan:
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
int res;
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
return luai_numlt(nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
return res;
return luaG_ordererror(L, l, r);
}
change:
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
int res;
if (ttype(l) == ttype(r)) {
if (ttisnumber(l))
return luai_numlt(nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
}
if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
return res;
return luaG_ordererror(L, l, r);
}
Current lessequal:
static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
int res;
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
return luai_numle(nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try
`le' */
return res;
else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try
`lt' */
return !res;
return luaG_ordererror(L, l, r);
}
change:
static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
int res;
if (ttype(l) == ttype(r)) {
if (ttisnumber(l))
return luai_numle(nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
}
if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
return res;
else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try
`lt' */
return !res;
return luaG_ordererror(L, l, r);
}
In the case of ==, the following ought to work:
in lvm.h:
#define equalobj(L,o1,o2) \
(ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
change to
#define equalobj(L,o1,o2) \
(ttype(o1) == ttype(o2) \
? luaV_equalval(L, o1, o2))
: call_orderTM(L, o1, o2) > 0
(However, you'd have to change call_orderTM to luaV_callOrderTM and add
it to the lvm.h header, I believe.)
I haven't tried any of that, and I'm don't think I like it. I would
certainly want to have an non-overridable object equality primitive in
the language ('is' '===' or however you spell it).