Skip to content

LuaTable behaves strangely (and uniquely) during type coercion #139

@Whoome

Description

@Whoome

NeoLua Version: 1.3.14

Setting up a simple example to demonstrate the odd, unexpected and (I think) undesirable behavior of LuaTable. In short LuaTable neither tries to coerce to type or just do nothing when used incorrectly as a parameter to a function. Rather it calls a default constructor (if one exists) and uses that.

I set up the following classes in C# to demonstrate

//Note that Foo is convertable to Bar
class Foo
{
    int m_value;

    public Foo()
    {
        m_value = 1071;
    }

    public Foo(int i)
    {
        m_value = i;
    }

    public int Value{ get{ return m_value; } }

    public override string ToString()
    {
        return string.Format("Foo({0})", Value);
    }
}

class Bar
{
    int m_value;
    public Bar(int i)
    {
        m_value = i;
    }

    public static implicit operator Foo(Bar b)
    {
        return new Foo(b.Value);
    }

    public int Value{ get{ return m_value; } }

    public override string ToString()
    {
        return string.Format("Bar({0})", Value);
    }
}

And the following functions exposed to the lua environment:

Foo MakeFoo(int i)
{
    return new Foo(i);
}

Bar MakeBar(int i)
{
    return new Bar(i);
}

void ProcessFoo(Foo f)
{
    PrintLine(string.Format("Processed {0}", f.ToString()));
}

void ProcessBar(Bar b)
{
    PrintLine(string.Format("Processed {0}", b.ToString()));
}

Example to reproduce:

>foo = MakeFoo(1)  --Setup for tests
>bar = MakeBar(2)
>ProcessFoo(foo)   --Process foo as foo
Processed Foo(1)
>ProcessBar(bar)   --Process bar as bar
Processed Bar(2)
>ProcessFoo(bar)  --Process bar as foo (calls conversion correctly)
Processed Foo(2)
>ProcessBar(foo)  --Process foo as bar: correctly fails to convert with good error
Exception: No conversion defined from Foo to Bar.
>ProcessFoo({})  --Process LuaTable as Foo:  GIVES SUPER WEIRD RESULT!  It called the empty constructor for Foo, and just went with it!
Processed Foo(1071)
>ProcessBar({})   --Process LuaTable as Bar: Fails weirdly too - why is it calling the default constructor?!?
Exception: Type 'Bar' does not have a default constructor
>ProcessBar("")  --Process a string as bar:  Behaves as expected gives an appropriate type coercion error
Exception: No coercion operator is defined between types 'System.String' and 'Bar'.

In general, I would expect LuaTable to act exactly as String or Foo or Bar do, if it is an inappropriate type to attempt type coercion, and if that is not possible, then I would expect an error.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions