Code Review: ClrMembers


#1

tfpt review “/shelveset:ClrMembers;REDMOND\tomat”

Adds the following methods to improve CLR interop:

  •      Kernel#clr_member
    

Returns RubyMethod that represents one or more CLR members (a field, an
event, a method, a group of overloaded methods, a property, an indexer,
an operator, etc.). Unlike Kernel#methods clr_member ignores Ruby
methods, undefined and removed methods. So even if a CLR is redefined by
a Ruby method definition clr_member will return it. It also ignores Ruby
inheritance hierarchy and returns members from all CLR super-types. For
example:

Array.ancestors

=> [Array, Enumerable, Object, Kernel]

Array.to_clr_type.base_type

=> System.Collections.Generic.List`1[System.Object]

[].method(:get_enumerator)

undefined method get_enumerator' for classArray’ (NameError)

[].clr_member(:get_enumerator)

=> #<Method: Array#get_enumerator>

[].clr_member(:get_enumerator).call

=> System.Collections.Generic.List`1+Enumerator[System.Object]

clr_member can’t be used on a Ruby class:

class C; new; end.clr_member(:p)

`C’ doesn’t represent a CLR type (TypeError)

  •      Class#clr_ctor/clr_constructor
    

Similar to clr_member. Returns a group of CLR constructors for given
class that represents a CLR type. A call to the resulting group will
return a new instance of the type. As with any method group, “overloads”
method could be used to select a particular overload. Examples:

puts Thread.clr_ctor.clr_members
Void .ctor(System.Threading.ThreadStart)
Void .ctor(System.Threading.ThreadStart, Int32)
Void .ctor(System.Threading.ParameterizedThreadStart)
Void .ctor(System.Threading.ParameterizedThreadStart, Int32)
=> nil

puts Thread.clr_ctor.overloads(System::Threading::ThreadStart).clr_members
Void .ctor(System.Threading.ThreadStart)
=> nil

Thread.clr_ctor.overloads(System::Threading::ThreadStart).call(lambda { puts ‘hello’ })
=> #<Thread:0x000005c unstarted>

  •      Class#clr_new
    

Creates an instance of the class using CLR constructors.

Splits RubyMethodGroupInfo into 2 classes: RubyOverloadGroupInfo <:
RubyMethodGroupInfo. The former participates in overload inheritance: it
comprises of overloads whose declaring types might differ and which
could be hidden by Ruby method definitions. More bookkeeping is needed
to support this. The latter is a simple group that groups arbitrary
methods and is created by selecting and grouping bunch of CLR methods
(e.g. using “overloads”, “of”, “clr_member”, “clr_ctor” methods).

Tomas


#2

Looks good, other than that ModuleOps.cs doesn’t appear to have any
changes in it =P
~js

From: Tomas M.
Sent: Sunday, May 31, 2009 10:06 PM
To: IronRuby External Code R.
Cc: removed_email_address@domain.invalid
Subject: Code Review: ClrMembers

tfpt review “/shelveset:ClrMembers;REDMOND\tomat”

Adds the following methods to improve CLR interop:

  •      Kernel#clr_member
    

Returns RubyMethod that represents one or more CLR members (a field, an
event, a method, a group of overloaded methods, a property, an indexer,
an operator, etc.). Unlike Kernel#methods clr_member ignores Ruby
methods, undefined and removed methods. So even if a CLR is redefined by
a Ruby method definition clr_member will return it. It also ignores Ruby
inheritance hierarchy and returns members from all CLR super-types. For
example:

Array.ancestors

=> [Array, Enumerable, Object, Kernel]

Array.to_clr_type.base_type

=> System.Collections.Generic.List`1[System.Object]

[].method(:get_enumerator)

undefined method get_enumerator' for classArray’ (NameError)

[].clr_member(:get_enumerator)

=> #<Method: Array#get_enumerator>

[].clr_member(:get_enumerator).call

=> System.Collections.Generic.List`1+Enumerator[System.Object]

clr_member can’t be used on a Ruby class:

class C; new; end.clr_member(:p)

`C’ doesn’t represent a CLR type (TypeError)

  •      Class#clr_ctor/clr_constructor
    

Similar to clr_member. Returns a group of CLR constructors for given
class that represents a CLR type. A call to the resulting group will
return a new instance of the type. As with any method group, “overloads”
method could be used to select a particular overload. Examples:

puts Thread.clr_ctor.clr_members
Void .ctor(System.Threading.ThreadStart)
Void .ctor(System.Threading.ThreadStart, Int32)
Void .ctor(System.Threading.ParameterizedThreadStart)
Void .ctor(System.Threading.ParameterizedThreadStart, Int32)
=> nil

puts Thread.clr_ctor.overloads(System::Threading::ThreadStart).clr_members
Void .ctor(System.Threading.ThreadStart)
=> nil

Thread.clr_ctor.overloads(System::Threading::ThreadStart).call(lambda { puts ‘hello’ })
=> #<Thread:0x000005c unstarted>

  •      Class#clr_new
    

Creates an instance of the class using CLR constructors.

Splits RubyMethodGroupInfo into 2 classes: RubyOverloadGroupInfo <:
RubyMethodGroupInfo. The former participates in overload inheritance: it
comprises of overloads whose declaring types might differ and which
could be hidden by Ruby method definitions. More bookkeeping is needed
to support this. The latter is a simple group that groups arbitrary
methods and is created by selecting and grouping bunch of CLR methods
(e.g. using “overloads”, “of”, “clr_member”, “clr_ctor” methods).

Tomas