[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: 0x102a70?
- From: Rici Lake <lua@...>
- Date: Sun, 30 Jan 2005 21:10:36 -0500
On 30-Jan-05, at 8:24 PM, PA wrote:
Ok... here is what I'm trying to do:
local anArray = { 1, 2, 3 }
local anotherArray = { 1, 2, 3 }
print( tostring( anArray == anotherArray ) )
This returns false. For my purpose, I would like it to return true as 
equality is defined by two arrays having the same content, not the 
same address.
You can do that by giving both tables the same __eq metamethod, 
although I'm not a great fan of that solution. See below.
Further more, consider a table with custom objects which may define 
their own notion of equality:
local aKey = LUObject.new()
local aValue = LUObject.new()
local aTable = { aKey = aValue }
aTable.aKey
How do I get 'aTable' to invoke 'aKey' equality methods to return the 
proper 'aValue'?
That is a slightly easier question: define __index and __newindex 
metamethods for aTable. However, you cannot then use table constructor 
syntax to construct it, which is a bit annoying; you need to do 
something like:
aTable = SpecialTable()
aTable.aKey = aValue
As a simple example, here is a table which ignores case in string keys 
(and blows up on non-string keys; a full solution is left for those who 
want it). (Remember that these
metamethods are only called if the key is not in the table.)
do
  local meta = {}
  function meta:__index(key)
    return rawget(self, string.tolower(key))
  end
  function meta:__newindex(key, value)
    rawset(self, string.tolower(key), value)
  end
  function CaseIgnoreTable()
    return setmetatable({}, meta)
  end
end
Note the difference between the __eq approach for equality (in which 
equality is defined by the compared values) and the above approach (in 
which equality is defined by the containing table).
Lua has no __hash metamethod (and I hope that it will not grow one 
either) although there is nothing stopping a courageous soul from 
reimplementing the table protocol with a userdata, which would then be 
free to do something like call getmetable(key).__hash. However, beware 
of hash methods which use the current value of a mutable key. (Here is 
another place where immutable tuples might be useful.)
Possibly a better approach would be to define your own interned 
immutable tuples, possibly using hash-consing.