I am using “for k, v in pairs()” to go through a table to see if a value is present. In this case, for example, I am looking for a vec2 object (i.e. “if v == someVector” ). Everything is fine, I can do an equality comparison “==“ against any other value in the table—vec2s, strings, numbers, tables, functions—until I put another userdata type in the table, say a color.
Then I something like this error: “[string “print( aColor == aVector )”]:1: bad argument #2 to ‘__eq’ (color)”
If I put them in the other order, I get a similar error “[string “print( aVector == aColor )”]:1: bad argument #-1 to ‘__eq’ (vec2)”
Is this expected? Is there a way around this, or should I just make sure that I don’t have different userdata types in the same table?
Thought I’d create an example based on @John post just to see how it would work.
function setup()
tab={}
tab[1]=1234
tab[2]="1234"
tab[3]={1,2,3,4}
tab[4]=xx
tab[5]=color(255,0,255)
tab[6]=vec2(12,34)
tab[7]=vec3(56,78,55)
tab[8]=vec4(56,78,55,12)
c=getmetatable(color())
v2=getmetatable(vec2())
v3=getmetatable(vec3())
v4=getmetatable(vec4())
for a,b in pairs(tab) do
print(a,type(b))
t=getmetatable(b)
if t==c then
print("equal to color")
end
if t==v2 then
print("equal to vec2")
end
if t==v3 then
print("equal to vec3")
end
if t==v4 then
print("equal to vec4")
end
end
end
function xx()
end
I was using this while testing some modifications to CodeaUnit, and that will do just fine.
So is this expected behavior? In a dynamically typed language, I feel that if aString == aTable can return false without throwing an error, so should userdataTypeA == userdataTypeB. Would this count as a bug?
On an unrelated note, I have found an action or two that reliably cause Codea to crash. Is it better to write that up in the Bugs forum or to use the BitBucket issue tracker?
Again, thank you both for showing me what to use and how to use it.
Just to throw in another example, here’s my is_a function which tests for equality of type, taken from the VecExt library on github:
--[[
The function "is_a" extends the capabilities of the method "is_a" which is automatically defined by Codea for classes.
Parameters:
a: object to be tested
b: test
The tests work as follows.
1. If the type of b is a string, it is taken as the name of a type to test a against.
2. If the type of b is a table, it is assumed to be a class to test if a is an instance thereof.
3. If the type of b is a userdata, the test is to see if a is the same type of object.
4. If b is a function, then it is replaced by the value of that function.
--]]
function is_a(a,b)
if type(b) == "function" then
b = b()
end
if type(b) == "table" and b.___type then
b = b()
end
if type(b) == "string" then
return type(a) == b
end
if type(b) == "table"
and type(a) == "table"
and a.is_a
then
return a:is_a(b)
end
if type(b) == "userdata"
and type(a) == "userdata"
then
if a.___type or b.___type then
return a.___type == b.___type
end
return getmetatable(a) == getmetatable(b)
end
return false
end