Improve __eq metatag processing.
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
print( '---- initial metatables' )
|
||||
local anumber = 111
|
||||
local aboolean = false
|
||||
local afunction = function() end
|
||||
local athread = coroutine.create( afunction )
|
||||
local atable = {}
|
||||
local anumber,bnumber = 111,23.45
|
||||
local astring,bstring = "abc","def"
|
||||
local anumstr,bnumstr = tostring(anumber),tostring(bnumber)
|
||||
local aboolean,bboolean = false,true
|
||||
local afunction,bfunction = function() end, function() end
|
||||
local athread,bthead = coroutine.create(afunction),coroutine.create(bfunction)
|
||||
local atable,btable = {},{}
|
||||
local values = { anumber, aboolean, afunction, athread, atable }
|
||||
for i=1,#values do
|
||||
print( debug.getmetatable( values[i] ) )
|
||||
end
|
||||
local groups
|
||||
local ts = tostring
|
||||
local tb,count = {},0
|
||||
|
||||
tostring = function(o)
|
||||
local t = type(o)
|
||||
if t~='thread' and t~='function' and t~='table' then return ts(o) end
|
||||
@@ -21,11 +21,23 @@ tostring = function(o)
|
||||
end
|
||||
|
||||
local buildop = function(name)
|
||||
return function(a,b)
|
||||
print( 'mt.__'..name..'()', a, b )
|
||||
return '__'..name..'-result'
|
||||
end
|
||||
end
|
||||
local buildop3 = function(name)
|
||||
return function(a,b,c)
|
||||
print( 'mt.__'..name..'()', a, b, c )
|
||||
return '__'..name..'-result'
|
||||
end
|
||||
end
|
||||
local buildop1 = function(name)
|
||||
return function(a)
|
||||
print( 'mt.__'..name..'()', a )
|
||||
return '__'..name..'-result'
|
||||
end
|
||||
end
|
||||
|
||||
local mt = {
|
||||
__call=buildop('call'),
|
||||
@@ -35,17 +47,12 @@ local mt = {
|
||||
__div=buildop('div'),
|
||||
__pow=buildop('pow'),
|
||||
__mod=buildop('mod'),
|
||||
__unm=buildop('unm'),
|
||||
__len=buildop('neg'),
|
||||
__eq=buildop('eq'),
|
||||
__unm=buildop1('unm'),
|
||||
__len=buildop1('len'),
|
||||
__lt=buildop('lt'),
|
||||
__le=buildop('le'),
|
||||
__tostring=function(a,b)
|
||||
return 'mt.__tostring('..type(a)..','..type(b)..')'
|
||||
end,
|
||||
__metatable={},
|
||||
__index=buildop('index'),
|
||||
__newindex=buildop('newindex'),
|
||||
__newindex=buildop3('newindex'),
|
||||
__concat=buildop('concat'),
|
||||
}
|
||||
|
||||
@@ -56,9 +63,48 @@ ecall = function(pattern, ...)
|
||||
return s,e
|
||||
end
|
||||
|
||||
print( '---- __eq same types' )
|
||||
local eqmt = { __eq=buildop('eq'), }
|
||||
groups = { {nil,nil}, {true,false}, {123,456}, {11,5.5}, {afunction,bfunction}, {athread,bthread}, {astring,bstring}, {anumber,anumstr} }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'before', pcall( function() return a~=b end ) )
|
||||
print( debug.setmetatable( a, eqmt ) )
|
||||
print( debug.setmetatable( b, eqmt ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a~=b end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __eq, tables - should invoke metatag comparison' )
|
||||
groups = { {atable,btable} }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'before', pcall( function() return a~=b end ) )
|
||||
print( debug.setmetatable( a, eqmt ) )
|
||||
print( debug.setmetatable( b, eqmt ) )
|
||||
print( type(a), type(b), 'after-a', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'after-a', pcall( function() return a~=b end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
|
||||
print( 'nilmt', debug.getmetatable(nil) )
|
||||
print( 'boolmt', debug.getmetatable(true) )
|
||||
print( 'number', debug.getmetatable(1) )
|
||||
print( 'function', debug.getmetatable(afunction) )
|
||||
print( 'thread', debug.getmetatable(athread) )
|
||||
|
||||
print( '---- __call' )
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(a), 'before', ecall( 'attempt to call', function() return a('a','b') end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( type(a), 'after', pcall( function() return a() end ) )
|
||||
@@ -66,13 +112,14 @@ for i=1,#values do
|
||||
print( type(a), 'after', pcall( function() return a('a','b') end ) )
|
||||
print( type(a), 'after', pcall( function() return a('a','b','c') end ) )
|
||||
print( type(a), 'after', pcall( function() return a('a','b','c','d') end ) )
|
||||
print( debug.setmetatable( a, nil ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
print( '---- __add, __sub, __mul, __div, __pow, __mod' )
|
||||
local groups = { {aboolean, aboolean}, {aboolean, athread}, {aboolean, afunction}, {aboolean, "abc"}, {aboolean, atable} }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a+b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b+a end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a-b end ) )
|
||||
@@ -94,29 +141,33 @@ for i=1,#groups do
|
||||
print( type(a), type(b), 'after', pcall( function() return b^a end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a%b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return b%a end ) )
|
||||
print( debug.setmetatable( a, nil ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __len' )
|
||||
values = { aboolean, afunction, athread }
|
||||
values = { aboolean, afunction, athread, anumber }
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(a), 'before', ecall( 'attempt to get length of ', function() return #a end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( type(a), 'after', pcall( function() return #a end ) )
|
||||
print( debug.setmetatable( a, nil ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
--
|
||||
print( '---- __neg' )
|
||||
values = { aboolean, afunction, athread, "abcd", atable }
|
||||
values = { aboolean, afunction, athread, "abcd", atable, anumber }
|
||||
for i=1,#values do
|
||||
print( type(values[i]), 'before', ecall( 'attempt to get length of ', function() return #values[i] end ) )
|
||||
print( debug.setmetatable( values[i], mt ) )
|
||||
print( type(values[i]), 'after', pcall( function() return #values[i] end ) )
|
||||
print( debug.setmetatable( values[i], nil ) )
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(v), 'before', ecall( 'attempt to perform arithmetic ', function() return -a end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( type(v), 'after', pcall( function() return -a end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
print( '---- __eq, __lt, __le, same types' )
|
||||
print( '---- __lt, __le, same types' )
|
||||
local bfunction = function() end
|
||||
local bthread = coroutine.create( bfunction )
|
||||
local btable = {}
|
||||
@@ -124,69 +175,59 @@ local groups
|
||||
groups = { {true, true}, {true, false}, {afunction, bfunction}, {athread, bthread}, {atable, atable}, {atable, btable} }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
print( type(a), type(b), 'before', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'before', pcall( function() return a~=b end ) )
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a<b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a<=b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>=b end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( debug.setmetatable( b, mt ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a~=b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a<b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a<=b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a>b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a>=b end ) )
|
||||
print( debug.setmetatable( a, nil ) )
|
||||
print( debug.setmetatable( b, nil ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __eq, __lt, __le, different types' )
|
||||
print( '---- __lt, __le, different types' )
|
||||
groups = { {aboolean, athread}, }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
print( type(a), type(b), 'before', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'before', pcall( function() return a~=b end ) )
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a<b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a<=b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>=b end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( debug.setmetatable( b, mt ) )
|
||||
print( type(a), type(b), 'after-a', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'after-a', pcall( function() return a~=b end ) )
|
||||
print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return a<b end ) )
|
||||
print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return a<=b end ) )
|
||||
print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return a>b end ) )
|
||||
print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return a>=b end ) )
|
||||
print( debug.setmetatable( a, nil ) )
|
||||
print( debug.setmetatable( b, nil ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __tostring' )
|
||||
values = { aboolean, afunction, athread, atable, "abc" }
|
||||
local strmt = { __tostring=function(a)
|
||||
return 'mt.__tostring('..type(a)..')'
|
||||
end,
|
||||
}
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
local amt = debug.getmetatable(a)
|
||||
print( debug.setmetatable( a, strmt ) )
|
||||
print( type(a), 'after', pcall( function() return ts(a) end ) )
|
||||
print( debug.setmetatable( a, nil ) )
|
||||
end
|
||||
|
||||
print( '---- __metatable' )
|
||||
values = { aboolean, afunction, athread, atable, "abc" }
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
print( type(a), 'before', pcall( function() return debug.getmetatable(a), getmetatable(a) end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( type(a), 'after', pcall( function() return debug.getmetatable(a), getmetatable(a) end ) )
|
||||
print( debug.setmetatable( a, nil ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
print( '---- __index, __newindex' )
|
||||
values = { aboolean, anumber, afunction, athread }
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(a), 'before', ecall( 'attempt to index', function() return a.foo end ) )
|
||||
print( type(a), 'before', ecall( 'attempt to index', function() return a[123] end ) )
|
||||
print( type(a), 'before', ecall( 'index', function() a.foo = 'bar' end ) )
|
||||
@@ -198,7 +239,7 @@ for i=1,#values do
|
||||
print( type(a), 'after', pcall( function() a.foo = 'bar' end ) )
|
||||
print( type(a), 'after', pcall( function() a[123] = 'bar' end ) )
|
||||
print( type(a), 'after', ecall( 'attempt to call', function() return a:foo() end ) )
|
||||
print( debug.setmetatable( a, nil ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
print( '---- __concat' )
|
||||
@@ -216,6 +257,7 @@ local concatmt = {
|
||||
}
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to concatenate ', function() return a..b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to concatenate ', function() return b..a end ) )
|
||||
print( type(a), type(s), type(t), 'before', ecall( 'attempt to concatenate ', function() return a..s..t end ) )
|
||||
@@ -227,6 +269,18 @@ for i=1,#groups do
|
||||
print( type(a), type(s), type(t), 'before', pcall( function() return a..s..t end ) )
|
||||
print( type(s), type(a), type(t), 'before', ecall( 'attempt to concatenate ', function() return s..a..t end ) )
|
||||
print( type(s), type(t), type(a), 'before', ecall( 'attempt to concatenate ', function() return s..t..a end ) )
|
||||
print( debug.setmetatable( a, nil ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __metatable' )
|
||||
values = { aboolean, afunction, athread, atable, "abc" }
|
||||
local mtmt = { __metatable={}, }
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(a), 'before', pcall( function() return debug.getmetatable(a), getmetatable(a) end ) )
|
||||
print( debug.setmetatable( a, mtmt ) )
|
||||
print( type(a), 'after', pcall( function() return debug.getmetatable(a), getmetatable(a) end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user