That's absolutely true for arbitrary CLR types. Library types (those marked by 
RubyClass attribute) are handled differently though. They can be seen like 
collections of extension methods. So it makes sense to extend a Ruby class 
using library methods. So far we were focused on extending CLR types using 
library types. Extending Ruby classes could be seen as a feature that is not 
implemented yet. Could you file a feature request (bug) on RubyForge?

A possible workaround for you: define a C# method that takes a Ruby class and 
extends it in manually using methods on RubyModule/RubyClass (AddMethod etc.). 
You would call this helper after loading the assembly.

Tomas

-----Original Message-----
From: ironruby-core-boun...@rubyforge.org 
[mailto:ironruby-core-boun...@rubyforge.org] On Behalf Of Curt Hagenlocher
Sent: Saturday, January 31, 2009 3:31 PM
To: ironruby-core@rubyforge.org
Subject: Re: [Ironruby-core] Extending modules defined in a ruby library via C#

.NET types can never be 100% compatible with Ruby classes; the semantics are 
simply too different.  What would you expect to happen, for instance, if you 
were to say the following:

module System::IDisposable; end
class System::Collections::ArrayList; include System::IDisposable; end;
x = System::Collections::ArrayList.new
require 'mscorlib'

Clearly, the "real" System::Collections::ArrayList can't implement IDisposable 
because the type is immutable.  And the type we created to represent the 
variable x can't be a "real" ArrayList because we didn't know about that class 
when x was allocated.

So this leaves us with two possibilities:
1) Always overwrite the previously defined constants with the newly imported 
CLR types
2) Fail to load the redefined types

...and we're currently doing the first.  While it seems reasonable to fail, it 
raises questions about what to do if 40 types can be loaded successfully but 
one can't be.  Do we raise an exception even though there were 40 successes?  
Or do we fail to load any types at all?

Monkey-patching CLR types is never going to be able to work identically to 
monkey-patching pure Ruby types.

-----Original Message-----
From: ironruby-core-boun...@rubyforge.org 
[mailto:ironruby-core-boun...@rubyforge.org] On Behalf Of Daniele Alessandri
Sent: Saturday, January 31, 2009 10:35 AM
To: ironruby-core@rubyforge.org
Subject: [Ironruby-core] Extending modules defined in a ruby library via C#

Hi,

I think I've stumbled on a bug of IronRuby, but I would like to hear your 
thoughts about this before filing a report on the bug tracker as I might be 
missing something or doing something wrong.

I have a ruby library in which is defined a module and this module holds a few 
classes and constants. Then I wrote a library in C# where the same module is 
defined to add more classes other than the ones defined on the ruby side. Now 
if I load the assembly first and then i require my ruby library everything 
works fine, but if I require the ruby library first and then load the assembly, 
the module defined by the ruby lib gets totally wiped off leaving there only 
what was defined in the assembly.

Given that in similar scenarios we obviously can't use Extends =
typeof(...) in the RubyModuleAttribute, shouldn't modules previously defined in 
ruby code be automatically extended instead of being erased/redefined (which is 
definitely broken)? Right below here you can find the code to reproduce and 
verify the reported behaviour (for convenience I also made an attachment to 
this mail).



# =========== foo.rb ===========
def test(a)
  a.each{ |s| puts "#{s} is #{begin eval(s); rescue NameError; 'undefined' 
end}"} end

module Foo
  class Bar; end
  VERSION = 1
end


/* ======== Nrk.Foo.Test.cs ======== */
namespace Nrk.Foo.Test {
    [RubyModule]
    public static class Foo {
        [RubyClass]
        public static class Hoge {
            [RubyMethod("piyo?", RubyMethodAttributes.PublicSingleton)]
            public static bool Piyo(Object self) {
                return true;
            }
        }
    }
}


# =========== test_assembly_first.rb =========== load_assembly 'Nrk.Foo.Test', 
'Nrk.Foo.Test'
require 'foo.rb'

test ['Foo', 'Foo::Bar', 'Foo::VERSION', 'Foo::Hoge', 'Foo::Hoge.piyo?']


# =========== test_ruby_first.rb =========== require 'foo.rb'
load_assembly 'Nrk.Foo.Test', 'Nrk.Foo.Test'

test ['Foo', 'Foo::Bar', 'Foo::VERSION', 'Foo::Hoge', 'Foo::Hoge.piyo?']


# =========== OUTPUT #1 ===========
Foo is Foo
Foo::Bar is Foo::Bar
Foo::VERSION is 1
Foo::Hoge is Foo::Hoge
Foo::Hoge.piyo? is true

# =========== OUTPUT #2 ===========
Foo is Foo
Foo::Bar is undefined
Foo::VERSION is undefined
Foo::Hoge is Foo::Hoge
Foo::Hoge.piyo? is true


--
Daniele Alessandri
http://www.clorophilla.net/blog/
_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org
http://rubyforge.org/mailman/listinfo/ironruby-core

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org
http://rubyforge.org/mailman/listinfo/ironruby-core

Reply via email to