I want to re-emphasize and expand a bit on what Tomas said: monkey-patching
.NET will only be visible from Ruby. You could look at this as a feature of
IronRuby as it will never break .NET code. In reality, it’s a limitation of the
CLR which does not allow modification of types once they are created.
Ivan, this is exactly why a special mocking framework needs to be built for
IronRuby =)
To make this a bit more concrete, here’s a simple example:
class Foo {
public int Bar() {
return 42;
}
public void SayBar() {
System.Console.WriteLine(Bar());
}
}
The SayBar() method is compiled to call the method Bar(). When this Ruby code
is executed:
class Foo
def Bar
“Monkey patched!”
end
end
The .NET “Foo” class is not changed, but a new type is created and the Ruby
method resolution knows to check this Ruby class first, then the “Foo” .NET
type (I’m drastically overly-simplifying the way method lookup works, but for
this example it’ll do =P). So when Bar() is called from Ruby it will give you
the Ruby method:
>>> Foo.new.Bar
=> “Monkey Patched!”
But the SayBar() method will always call the static version of Bar(), because
monkey-patching has no effect on the .NET view of the world.
>>> Foo.new.SayBar
42
=> nil
The only way to truly modify the “.NET-view” from Ruby is via
System.Reflection. Today C# code can only call into DLR code by using the DLR
Hosting API, though as Tomas mentioned that is improving in C#4.
I’ll add this to the wiki, as I’m beginning to build up our .NET integration
documentation … keep asking questions like this to make my life easier =)
~Jimmy
From: [email protected]
[mailto:[email protected]] On Behalf Of Tomas Matousek
Sent: Wednesday, May 13, 2009 9:37 AM
To: [email protected]
Subject: Re: [Ironruby-core] more interop questions
It’s pretty simple: your can define a Ruby method on any class/interface. The
method will only be visible from Ruby unless the class is a Ruby dynamic object
(implements IDynamicObjectProvider using Ruby binders). For such dynamic
objects Ruby methods will be available when invoked from dynamic expression in
C# 4.0. The methods are also invokable via ObjectOperations class in Hosting
API.
Tomas
From: [email protected]
[mailto:[email protected]] On Behalf Of Ivan Porto Carrero
Sent: Wednesday, May 13, 2009 9:20 AM
To: ironruby-core
Subject: Re: [Ironruby-core] more interop questions
I know these sound like pretty basic questions.. but I'm playing devil's
advocate here (maybe rubyist advocate is better suited) and I imagine I will
need a good chunk in a chapter somewhere to explain this stuff really clearly.
---
Met vriendelijke groeten - Best regards - Salutations
Ivan Porto Carrero
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)
On Wed, May 13, 2009 at 5:57 PM, Ivan Porto Carrero
<[email protected]<mailto:[email protected]>> wrote:
Hi
I got into a discussion with Roy Osherhove about overriding statics.
I know in C# it can't be done obviously and as long as I stay in Ruby you can.
I understand this may seem like straight-forward stuff. Can you give me a
pointer where I can take stock of what I can and can't do to CLR objects and in
which cases ruby things apply?
But when you go back and call it from a C# class it takes the CLR implementation
public class MyClassWithAStatic{
public string HelloWorld(){
return "Hello World!";
}
public static string GoodByeWorld(){
return "Goodbye world!";
}
}
public class StaticCaller{
public string CallsStatic(){
return MyClassWithAStatic.GoodByeWorld();
}
}
console session:
(master) » ir
IronRuby 0.4.0.0 on .NET 2.0.50727.4918
Copyright (c) Microsoft Corporation. All rights reserved.
>>> require 'spec/bin/ClrModels.dll'
=> true
>>> include ClrModels
=> Object
>>> MyClassWithAStatic
=> ClrModels::MyClassWithAStatic
>>> MyClassWithAStatic.good_bye_world
=> 'Goodbye world!'
>>> sc = StaticCaller.new
=> ClrModels.StaticCaller
>>> sc.calls_static
=> 'Goodbye world!'
>>> class MyClassWithAStatic
... def self.good_bye_world
... "From Ruby we say goodbye to you"
... end
... end
=> nil
>>> MyClassWithAStatic.good_bye_world
=> "From Ruby we say goodbye to you"
>>> sc = StaticCaller.new
=> ClrModels.StaticCaller
>>> sc.calls_static
=> 'Goodbye world!'
New session to figure out if something could be done before the type was
actually created
+ C:\dev\caricature
(master) » ir
IronRuby 0.4.0.0 on .NET 2.0.50727.4918
Copyright (c) Microsoft Corporation. All rights reserved.
>>> require 'spec/bin/ClrModels.dll'
=> true
>>> class MyClassWithAStatic
... def self.good_bye_world
... "From Ruby we say goodbye to you"
... end
... end
=> nil
>>> ClrModels::StaticCaller.new.calls_static
=> 'Goodbye world!'
---
Met vriendelijke groeten - Best regards - Salutations
Ivan Porto Carrero
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)
Don Marquis<http://www.brainyquote.com/quotes/authors/d/don_marquis.html> -
"Procrastination is the art of keeping up with yesterday."
_______________________________________________
Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core