lua-users home
lua-l archive

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

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 =
local aValue =
local aTable = { aKey = aValue }


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.)

  local meta = {}

  function meta:__index(key)
    return rawget(self, string.tolower(key))

  function meta:__newindex(key, value)
    rawset(self, string.tolower(key), value)

  function CaseIgnoreTable()
    return setmetatable({}, meta)

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.