Discussion:
overriding string __eq as in: if {} == "string"
Andrew Cagney
2015-06-16 15:42:51 UTC
Permalink
Hi,

I'd like to change the behaviour of __eq when applied to strings. I
suspect I'll need to somehow change the underlying string type?

My attempt at this was along the lines of:

Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
m={}
function m:__eq(rhs)
print("in _eq")
return true
end
t = {}
setmetatable(t, m)
if t == "string" then
print("true")
else
print("false")
end
false
q = {}
setmetatable(q,m)
if t == q then
print("true")
else
print("false")
end
in _eq
true
while the problem could be with my code, I suspect it is related to this:

2.4 – Metatables and Metamethods
[...] "eq": the == (equal) operation. Behavior similar to the "add"
operation, except that Lua will try a metamethod only when the values
being compared are either both tables or both full userdata and they
are not primitively equal. The result of the call is always converted
to a boolean.

Anyway, does anyone have a pointer or example showing how to do
override __eq (and string operations more generally).

--[[

The objective here is to fully integrate my objects into Lua. That
is, expressions such as:
o = "string"
i = i+1
if i == 1 or o == "string" then
all appear to behave as expected yet, underneath, they are using
meta-methods such as __setindex, __add, and __eq to perform
operations.

]]

Andrew
Dirk Laurie
2015-06-16 17:04:16 UTC
Permalink
Post by Andrew Cagney
I'd like to change the behaviour of __eq when applied to strings. I
suspect I'll need to somehow change the underlying string type?
2.4 – Metatables and Metamethods
[...] "eq": the == (equal) operation. Behavior similar to the "add"
operation, except that Lua will try a metamethod only when the values
being compared are either both tables or both full userdata and they
are not primitively equal. The result of the call is always converted
to a boolean.
Anyway, does anyone have a pointer or example showing how to do
override __eq (and string operations more generally).
The objective here is to fully integrate my objects into Lua. That
o = "string"
i = i+1
if i == 1 or o == "string" then
The first line creates a value of type string and stores it in _ENV.o
unless you have overridden __newindex in _ENV, a risky thing to do.
And as the docs state, __eq will not be invoked in the third line.

What you can do is to redefine stuff not normally used for strings.
E.g. you can redefine string_mt.__not to be a constructor for your
wrapper type and string_mt.__xor and to be your intended __eq.
Then the following will work:

o = ~"string"
i = i+1
if i == 1 or o ~ "string" then
Andrew Cagney
2015-06-16 18:01:19 UTC
Permalink
Post by Dirk Laurie
Post by Andrew Cagney
The objective here is to fully integrate my objects into Lua. That
o = "string"
i = i+1
if i == 1 or o == "string" then
The first line creates a value of type string and stores it in _ENV.o
unless you have overridden __newindex in _ENV, a risky thing to do.
And as the docs state, __eq will not be invoked in the third line.
Yes, I'm taking that risk. __index and __newindex are overridden.
That way things like:

print(a,b) -- global __index creates values for "a" and "b" on-demand
a = b -- update "a" with b using __setindex

work the way I'd like.
Post by Dirk Laurie
What you can do is to redefine stuff not normally used for strings.
E.g. you can redefine string_mt.__not to be a constructor for your
wrapper type and string_mt.__xor and to be your intended __eq.
o = ~"string"
i = i+1
if i == 1 or o ~ "string" then
or as a first cut:

o == ~"string"

while not, from my personal pov, ideal it does let me move forward.

Andrew
Andrew Starks
2015-06-17 02:29:48 UTC
Permalink
Post by Andrew Cagney
Post by Dirk Laurie
Post by Andrew Cagney
The objective here is to fully integrate my objects into Lua. That
o = "string"
i = i+1
if i == 1 or o == "string" then
The first line creates a value of type string and stores it in _ENV.o
unless you have overridden __newindex in _ENV, a risky thing to do.
And as the docs state, __eq will not be invoked in the third line.
Yes, I'm taking that risk. __index and __newindex are overridden.
print(a,b) -- global __index creates values for "a" and "b" on-demand
a = b -- update "a" with b using __setindex
work the way I'd like.
Post by Dirk Laurie
What you can do is to redefine stuff not normally used for strings.
E.g. you can redefine string_mt.__not to be a constructor for your
wrapper type and string_mt.__xor and to be your intended __eq.
o = ~"string"
i = i+1
if i == 1 or o ~ "string" then
o == ~"string"
while not, from my personal pov, ideal it does let me move forward.
Andrew
Hey Andrew,
Post by Andrew Cagney
From my experience, overriding the basic types is not as awesome as
making new "objects" with tables. You can make string-like object by
overloading __concat and __tostring and __eq.

Overloading string is something that I've had great fun, but I have a
Url object that starts life as a table and it seems to work pretty
well.

-Andrew
书呆彭, Peng Yi
2015-06-17 01:57:07 UTC
Permalink
Post by Andrew Cagney
Hi,
I'd like to change the behaviour of __eq when applied to strings. I
suspect I'll need to somehow change the underlying string type?
<...>
Anyway, does anyone have a pointer or example showing how to do
override __eq (and string operations more generally).
meta-method in Lua is not a mechanism to override but as a fallback.
Post by Andrew Cagney
The objective here is to fully integrate my objects into Lua.
I don't exactly know your use case, but I guess you might want
to consider userdata; userdata is normally for users to create
custom data types.
--
the nerdy Peng / 书呆彭 / Sent from Thunderbird
Brigham Toskin
2015-06-17 18:11:38 UTC
Permalink
Post by 书呆彭, Peng Yi
Post by Andrew Cagney
Hi,
I'd like to change the behaviour of __eq when applied to strings. I
suspect I'll need to somehow change the underlying string type?
<...>
Anyway, does anyone have a pointer or example showing how to do
override __eq (and string operations more generally).
meta-method in Lua is not a mechanism to override but as a fallback.
__len() would disagree. Unless you meant __eq specifically, but then I
think we're getting into a semantic argument, and I'm not sure we would be
arguing different things, really.
--
Brigham Toskin
Dirk Laurie
2015-06-17 18:47:11 UTC
Permalink
Post by Brigham Toskin
Post by 书呆彭, Peng Yi
meta-method in Lua is not a mechanism to override but as a fallback.
__len() would disagree.
Basically Peng Yi is correct. __len was a very late addition to Lua (5.2)
and is the only example of a core ability depending on a metamethod.

Fallbacks date back to Lua 2.1. They became "tag methods" in Lua 3.0 and
metamethods in 5.0. There was some semantic reason each time for the
name change, but for __add, __eq and friends, a metamethod remains
something that is only invoked when Lua does not know what to do.
Loading...