0.9.1 regression when creating System::Array of clr enum values

I have a CLR dll which declares an enumeration FieldID. It’s just an
ordinary C# enum
I have the following code which used to work under 0.9

fields_to_read = [FieldID.DBID, FieldID.Name]
clr_fields = System::Array[FieldID].new fields_to_read

Under 0.9.1, the following exception occurs:

System::InvalidCastException: The result type ‘System.Int32’ of the
dynamic
binding produced by binder ‘ConvertToFixnumAction @1’ is not compatible
with
the result type ‘Interop.FieldID’ expected by the call site.
from Microsoft.Scripting.Core:0:in Bind' from Microsoft.Scripting.Core:0:inBindCore’
from (irb):71
from :0:in eval' from workspace.rb:80:inevaluate’
from context.rb:217:in evaluate' from irb.rb:147:ineval_input’
from irb.rb:257:in signal_status' from irb.rb:146:ineval_input’
from ruby-lex.rb:230:in each_top_level_statement' from :0:inloop’
from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:146:in eval_input' from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:70:instart’
from :0:in catch' from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:69:instart’
from C:/Dev/TEST/ruby/bin/iirb:13

Has the behavior for converting ruby arrays to CLR arrays changed? I’m
working around it for now by doing this:

tmp = System::Collections::Generic::List.of(FieldID).new
fields_to_read.each{|f| tmp.add f}
clr_fields = tmp.to_array

Note: I wanted to just pass the fields_to_read ruby array into the
constructor of List, but when I do this, IronRuby is selecting the
constructor overload which takes an int32 for capacity, rather than the
overload which takes IEnumerable, and I get the following error:

tmp = System::Collections::Generic::List.of(FieldID).new(fields_to_read)
TypeError: can’t convert Array into Fixnum
from (irb):75
from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:146:in eval_input' from :0:ineval’
from workspace.rb:80:in evaluate' from context.rb:217:inevaluate’
from irb.rb:147:in eval_input' from irb.rb:257:insignal_status’
from irb.rb:146:in eval_input' from ruby-lex.rb:230:ineach_top_level_statement’
from :0:in loop' from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:70:instart’
from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:69:in start' from :0:incatch’
from C:/Dev/TEST/ruby/bin/iirb:13

Is this also a bug?

Thanks a lot, Orion

The error message seems to indicate this is the same issue you had in
your “Another 0.9.1 regression” mail.

From: [email protected]
[mailto:[email protected]] On Behalf Of Orion E.
Sent: Tuesday, September 29, 2009 3:32 PM
To: [email protected]
Subject: [Ironruby-core] 0.9.1 regression when creating System::Array of
clr enum values

I have a CLR dll which declares an enumeration FieldID. It’s just an
ordinary C# enum

I have the following code which used to work under 0.9

fields_to_read = [FieldID.DBID, FieldID.Name]
clr_fields = System::Array[FieldID].new fields_to_read

Under 0.9.1, the following exception occurs:

System::InvalidCastException: The result type ‘System.Int32’ of the
dynamic binding produced by binder ‘ConvertToFixnumAction @1’ is not
compatible with the result type ‘Interop.FieldID’ expected by the call
site.
from Microsoft.Scripting.Core:0:in Bind' from Microsoft.Scripting.Core:0:in BindCore’
from (irb):71
from :0:in eval' from workspace.rb:80:in evaluate’
from context.rb:217:in evaluate' from irb.rb:147:in eval_input’
from irb.rb:257:in signal_status' from irb.rb:146:in eval_input’
from ruby-lex.rb:230:in each_top_level_statement' from :0:in loop’
from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:146:in eval_input' from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:70:in start’
from :0:in catch' from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:69:in start’
from C:/Dev/TEST/ruby/bin/iirb:13

Has the behavior for converting ruby arrays to CLR arrays changed? I’m
working around it for now by doing this:

tmp = System::Collections::Generic::List.of(FieldID).new
fields_to_read.each{|f| tmp.add f}
clr_fields = tmp.to_array

Note: I wanted to just pass the fields_to_read ruby array into the
constructor of List, but when I do this, IronRuby is selecting the
constructor overload which takes an int32 for capacity, rather than the
overload which takes IEnumerable, and I get the following error:

tmp = System::Collections::Generic::List.of(FieldID).new(fields_to_read)
TypeError: can’t convert Array into Fixnum
from (irb):75
from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:146:in eval_input' from :0:in eval’
from workspace.rb:80:in evaluate' from context.rb:217:in evaluate’
from irb.rb:147:in eval_input' from irb.rb:257:in signal_status’
from irb.rb:146:in eval_input' from ruby-lex.rb:230:in each_top_level_statement’
from :0:in loop' from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:70:in start’
from C:/Dev/TEST/ruby/lib/ruby/1.8/irb.rb:69:in start' from :0:in catch’
from C:/Dev/TEST/ruby/bin/iirb:13

Is this also a bug?

Thanks a lot, Orion

Hrm… I’m trying to get some sample code so I can provide a repro for
you
guys, but it’s proving difficult. The following C# code is all fine
when
called from IronRuby

public static class II
{
public static void GetData(this string str, int inint, out int
outint,
out string outstr)
{
outint = inint * 10;
outstr = outint.ToString();
Console.WriteLine(“str=”+str);
}

public static void GetXHR(this string str, out 

MSXML2.IXMLHTTPRequest
xhr)
{
xhr = new MSXML2.XMLHTTPClass();
}

public static void GetDualXhrFromCoClass(this string str, out

MSXML2.IXMLHTTPRequest xhr1, out MSXML2.IXMLHTTPRequest xhr2)
{
xhr1 = new MSXML2.XMLHTTPClass();
xhr2 = new MSXML2.XMLHTTPClass();
}

public static void GetDualXhrFromCLSID(this string str, out object 

xhr1,
out object xhr2)
{
var t = Type.GetTypeFromCLSID(new
Guid(“F6D90F16-9C73-11D3-B32E-00C04F990BB4”)); // guid of
MSXML2.XMLHTTPClass
xhr1 = Activator.CreateInstance(t);
xhr2 = Activator.CreateInstance(t);
}

public static void GetDualXhrWithCast(this string str, out

MSXML2.IXMLHTTPRequest xhr1, out MSXML2.IXMLHTTPRequest xhr2)
{
var t = Type.GetTypeFromCLSID(new
Guid(“F6D90F16-9C73-11D3-B32E-00C04F990BB4”)); // guid of
MSXML2.XMLHTTPClass
xhr1 = Activator.CreateInstance(t) as MSXML2.IXMLHTTPRequest;
xhr2 = Activator.CreateInstance(t) as MSXML2.IXMLHTTPRequest;
}
}

On Wed, Sep 30, 2009 at 12:19 PM, Jimmy S. <

On Wed, Sep 30, 2009 at 12:19 PM, Jimmy S. <
[email protected]> wrote:

The error message seems to indicate this is the same issue you had in your
“Another 0.9.1 regression” mail.

Really? The repro for this one is really simple and has no COM at all.

C# code:

public enum Fields
{
None = 0,
DBID = 1,
Name = 2
}

Ruby code

require ‘scratchdll’
f = [Fields.DBID, Fields.Name]
System::Array[Fields].new f

=>
System::InvalidCastException: The result type ‘System.Int32’ of the
dynamic
binding produced by binder ‘ConvertToFixnumA
ction @1’ is not compatible with the result type ‘Fields’ expected by
the
call site.
from Microsoft.Scripting.Core:0:in Bind' from Microsoft.Scripting.Core:0:inBindCore’

Cheers, Orion

I think we actually already have this reported on CodePlex:

http://ironruby.codeplex.com/WorkItem/View.aspx?WorkItemId=2490

Tomas

From: [email protected]
[mailto:[email protected]] On Behalf Of Orion E.
Sent: Tuesday, September 29, 2009 4:52 PM
To: [email protected]
Subject: Re: [Ironruby-core] 0.9.1 regression when creating
System::Array of clr enum values

On Wed, Sep 30, 2009 at 12:19 PM, Jimmy S.
<[email protected]mailto:[email protected]>
wrote:

The error message seems to indicate this is the same issue you had in
your “Another 0.9.1 regression” mail.

Really? The repro for this one is really simple and has no COM at all.

C# code:

public enum Fields
{
None = 0,
DBID = 1,
Name = 2
}

Ruby code

require ‘scratchdll’
f = [Fields.DBID, Fields.Name]
System::Array[Fields].new f

=>
System::InvalidCastException: The result type ‘System.Int32’ of the
dynamic binding produced by binder ‘ConvertToFixnumA
ction @1’ is not compatible with the result type ‘Fields’ expected by
the call site.
from Microsoft.Scripting.Core:0:in Bind' from Microsoft.Scripting.Core:0:in BindCore’

Cheers, Orion