Comparison Error with userdata types

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?

Thanks!

@AlbertEinlime you could do check if they both have the same metatable first then check for equality

if getmetatable(value1) == getmetatable(value2) and value1 == value2 then
...
end

This way only things that are the same type (in terms of userdata) will be compared.

I assume you’re using type to determine what’s in the table. Can you show a little demo of what you’re doing.

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

Thank you @John, @dave1707,

That’s what I was looking for.

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