[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: absence of a __hash metamethod
- From: Asko Kauppi <askok@...>
- Date: Thu, 15 Nov 2007 09:02:37 +0200
Programming in Lua as in any language has a certain mindset, which
makes one do things "the Lua way". So maybe the reason you need a
'signature' for table contents is because of doing something unlike
Lua in higher levels.
Having said that, I actually had the same need yesterday (first time
ever) and made the following code. This is for caching products based
on table contents, so earlier products can be reused. Please take use
of the code, if you like. Disclaimer: not tested yet!
Note that even if Lua had a hash metamethod for tables, it wouldn't
give same hash for different tables of equal contents.
-----
-- str= table_id(tbl)
--
-- Returns a unique ID for the assert template table; subsequent
calls must
-- give the exact same string.
--
-- { [tbl/assert_func [, ...] [, true]], [name= tbl/assert_func [,
name2= tbl/assert_func]] }
--
local function table_id( t )
local sort= {} -- parts collected: "num=..." "name=..."
-- Collect IDs for each key
--
for k,v in pairs(t) do
local tv= type(v)
local s
if tv=="table" then
s= "{"..table_id(v).."}"
elseif tv=="function"
-- tostring(func) gives "function: 0xNNNNN"; the
"function: " is
-- unnecessary for us but it does not really matter
(except for
-- the cached memory strings taking up some bytes)
--
s= string.gsub( tostring(v), "function: ", "", 1 )
else
assert( v==true )
s= true
end
sort[#sort]= k.."="..s
end
table.sort( sort )
return table.concat( sort, "," )
end
Peter Cawley kirjoitti 14.11.2007 kello 23:13:
The 0x12345678 value produces by tostring is the pointer to the
object. As the table is being regenerated each time, this value will
vary:
a = {1,2,3}
b = {1,2,3}
= tostring(a)
table: 003297C8
= tostring(b)
table: 003299F0
a = {1,2,3}
= tostring(a)
table: 0032B138
On 14/11/2007, Patrick Donnelly <batrick.donnelly@gmail.com> wrote:
I'm not saying this is the most efficient way, but here's
something you can do:
hold = {}
somenewtable = {}
hold[somenewtable] = true
hold[tostring(somenewtable)] = somenewtable
print(tostring(somenewtable))
print(tostring(somenewtable))
table: 0x807b6a0
Notice tostring on a table produces a unique string identifier for
that table... You can use it as your "hash".
--
-Patrick Donnelly
"One of the lessons of history is that nothing is often a good thing
to do and always a clever thing to say."
-Will Durant