Calling constructor when static .New() method is defined

Shay F. suggested I’d post this to the mailing list, as it may be
a bug in IronRuby:

It seems impossible to call a constructor when there is a static .New()
method defined on a class.

This is a minimal test case demonstrating the problem:

.NET (C#) class:

public class Tester
{
    public static void New()
    {
        Console.WriteLine("In Tester.New()");
    }

    public Tester()
    {
        Console.WriteLine("In constructor");
    }
}

IronRuby code:

Tester.new
Tester.New

The ruby code above calls Tester.New() in both cases. There seems to be
no way to call the regular constructor of this class.

You can call CLR constructor using “clr_new” method:

Tester.clr_new

Tomas

Thanks, that does seem to work.

But I personally think this behavior is completely wrong. Calling .new
from IronRuby should always call the constructor, not a static method
named .New() that happens to exist somewhere in the class hierarchy. (if
the .New() method is defined in a base class, you get the same problem).

Philippe

Philippe Leybaert wrote:

But I personally think this behavior is completely wrong. Calling .new from
IronRuby should always call the constructor, not a static method named
.New() that happens to exist somewhere in the class hierarchy. (if the
.New() method is defined in a base class, you get the same problem).

“new” is just a Ruby method on the Class object, which Ruby happens to
call to construct an object. Because it’s just a method, it can be
overridden. For example, a Ruby class’s #new can be overridden to return
ANY object.

class Foo
… def self.new
… 42
… end
… end
=> nil

Foo.new
=> 42

Foo.new.class
=> Fixnum

So, anywhere in the class hierarchy, #new can be overridden. For
example, if a base class overrides new, it does so for all its
subclasses also, just as normal inheritance tells it do:

class Bar < Foo
… end
=> nil

Bar.new
=> 42

At a high-level, the way IronRuby’s .NET interop works is by treating
any .NET-based code as if it were Ruby code, so a CLR Type will be shown
as a Ruby Class. Therefore, defining a “New” method in C# is the moral
equivalent of defining “new” on any Ruby class, which will override
Class#new, which in turn overrides the CLR .ctor. Which is why “clr_new”
is provided.

~js

I said “#new” in some places where I shouldn’t have … so corrected
below in case there was some confusion …