Forum: IronRuby more interop questions

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ivan P. (Guest)
on 2009-05-13 20:01
(Received via mailing list)
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 C.
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_ma...
- "Procrastination is the art of keeping up with yesterday."
Ivan P. (Guest)
on 2009-05-13 20:23
(Received via mailing list)
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 C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)
Tomas M. (Guest)
on 2009-05-13 20:42
(Received via mailing list)
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: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] 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 C.
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 C.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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 C.
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_ma...  -
"Procrastination is the art of keeping up with yesterday."
Jimmy S. (Guest)
on 2009-05-13 21:14
(Received via mailing list)
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: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Tomas M.
Sent: Wednesday, May 13, 2009 9:37 AM
To: removed_email_address@domain.invalid
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: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] 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 C.
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 C.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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 C.
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_ma...  -
"Procrastination is the art of keeping up with yesterday."
Shri B. (Guest)
on 2009-05-13 23:48
(Received via mailing list)
For the devil’s advocate position Ivan was arguing for, you could argue
that IronRuby should only allow *adding* new members to CLR types, not
to edit or delete existing CLR members. The added members would be
visible only from Ruby. From C#, you will get compiler errors anyway if
you try to call these added members (unless you use “dynamic” in C#
4.0), and so having two different views of the CLR type is OK here since
there is no scope for confusion.

This would be somewhat similar to the way C# extension methods work –
the real methods of the type get precedence, and extension methods
(comparable to monkey-patched Ruby methods) get lower precedence during
overload resolution.

Building a special mocking framework for IronRuby does not change the
basic fact that CLR types are unmodifiable. A special framework will
work only if the app is all IronRuby code, but it will break when C# is
thrown in the mix.

The current plan is to allow monkey-patching of CLR members on CLR
types. It does give power but has some unpredictability as well.
Feedback and real-world experience is welcome about whether this is the
right thing or not.

From: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Jimmy
Schementi
Sent: Wednesday, May 13, 2009 10:03 AM
To: removed_email_address@domain.invalid
Subject: Re: [Ironruby-core] more interop questions

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: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Tomas M.
Sent: Wednesday, May 13, 2009 9:37 AM
To: removed_email_address@domain.invalid
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: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] 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 C.
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 C.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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 C.
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_ma...  -
"Procrastination is the art of keeping up with yesterday."
Stefan D. (Guest)
on 2009-05-14 00:21
(Received via mailing list)
I suppose we will get the dynamic behavior if the Foo changes like this:

class Foo {

  public *dynamic *Bar() {

    return 42;

  }

  public void SayBar() {

    System.Console.WriteLine(Bar());

  }

}
Right?

2009/5/13 Jimmy S. <removed_email_address@domain.invalid>
Tomas M. (Guest)
on 2009-05-14 00:34
(Received via mailing list)
You still won't see Ruby methods on the boxed 42 object since it is CLR
object and not a Ruby object. C# only sees Ruby methods on Ruby objects
(those that implement IDynamicMetaObjectProvider interface).

Tomas

From: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Stefan D.
Sent: Wednesday, May 13, 2009 12:57 PM
To: removed_email_address@domain.invalid
Subject: Re: [Ironruby-core] more interop questions

I suppose we will get the dynamic behavior if the Foo changes like this:

class Foo {

  public dynamic Bar() {

    return 42;

  }

  public void SayBar() {

    System.Console.WriteLine(Bar());

  }

}
Right?
2009/5/13 Jimmy S.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>>

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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Tomas M.
Sent: Wednesday, May 13, 2009 9:37 AM
To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>

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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Ivan Porto C.
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 C.

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 C.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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 C.
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_ma...  -
"Procrastination is the art of keeping up with yesterday."
Curt H. (Guest)
on 2009-05-14 00:37
(Received via mailing list)
You only get the dynamic behavior from C# if the actual underlying type
implements IDynamicMetaObjectProvider. In this case, Bar() returns an
object of type "System.Int32" - which does not implement that interface.

From: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Stefan D.
Sent: Wednesday, May 13, 2009 12:57 PM
To: removed_email_address@domain.invalid
Subject: Re: [Ironruby-core] more interop questions

I suppose we will get the dynamic behavior if the Foo changes like this:

class Foo {

  public dynamic Bar() {

    return 42;

  }

  public void SayBar() {

    System.Console.WriteLine(Bar());

  }

}
Right?
2009/5/13 Jimmy S.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>>

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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Tomas M.
Sent: Wednesday, May 13, 2009 9:37 AM
To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>

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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Ivan Porto C.
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 C.

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 C.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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 C.
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_ma...  -
"Procrastination is the art of keeping up with yesterday."
Ivan P. (Guest)
on 2009-05-14 00:45
(Received via mailing list)
o right.. so implementing that interface on any CLR type would be enough
to
make it play nice?
---
Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

Jay Leno <http://www.brainyquote.com/quotes/authors/j/jay_le...  -
"Don't forget Mother's Day. Or as they call it in Beverly Hills, Dad's
Third
Wife Day."
Ivan P. (Guest)
on 2009-05-14 00:51
(Received via mailing list)
Well actually at this point I have progressed in searching for a way to
cheat.But I didn't find a way yet that will work with signed 3rd party
signed assemblies like say sharepoint.

I can use Mono.Cecil to change some of the types to include AOP hooks so
I
can inject ruby in them and get the expected result by just not calling
the
real method body. That should work for everything that isn't signed.  if
the
signed assemblies aren't being referenced by anything else than your
source
code then that will still work by recompiling the source code against
the
new assemblies.

I think that should get me pretty far in what I'm trying to achieve with
the
mocker.
I need to be able to intercept the method call, execute ruby and decide
whether or not to call the previous method.

Then I'm only stuck on how to get around 3rd party signed assemblies
with
keys that I don't have access to.

In my case the expected result is when I'm working from ruby things
should
behave like ruby. So if I monkey patch some method it should just
replace
the thing also when C# calls it :)


---
Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

Vince
Lombardi<http://www.brainyquote.com/quotes/authors/v/vince_...
- "We didn't lose the game; we just ran out of time."
Shri B. (Guest)
on 2009-05-14 01:02
(Received via mailing list)
If you really want to push the envelope that far, you can use the
Profiling APIs (http://msdn.microsoft.com/en-us/magazine/cc300553.aspx)
to replace the IL method bodies. That will work with signed assemblies,
and you don’t need to change any source code either. Its very powerful,
but pretty complicated as well.

From: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Ivan Porto
Carrero
Sent: Wednesday, May 13, 2009 1:47 PM
To: removed_email_address@domain.invalid
Subject: Re: [Ironruby-core] more interop questions

Well actually at this point I have progressed in searching for a way to
cheat.
But I didn't find a way yet that will work with signed 3rd party signed
assemblies like say sharepoint.

I can use Mono.Cecil to change some of the types to include AOP hooks so
I can inject ruby in them and get the expected result by just not
calling the real method body. That should work for everything that isn't
signed.  if the signed assemblies aren't being referenced by anything
else than your source code then that will still work by recompiling the
source code against the new assemblies.

I think that should get me pretty far in what I'm trying to achieve with
the mocker.
I need to be able to intercept the method call, execute ruby and decide
whether or not to call the previous method.

Then I'm only stuck on how to get around 3rd party signed assemblies
with keys that I don't have access to.

In my case the expected result is when I'm working from ruby things
should behave like ruby. So if I monkey patch some method it should just
replace the thing also when C# calls it :)


---
Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

Vince
Lombardi<http://www.brainyquote.com/quotes/authors/v/vince_...
- "We didn't lose the game; we just ran out of time."
On Wed, May 13, 2009 at 9:41 PM, Shri B.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
wrote:

For the devil’s advocate position Ivan was arguing for, you could argue
that IronRuby should only allow *adding* new members to CLR types, not
to edit or delete existing CLR members. The added members would be
visible only from Ruby. From C#, you will get compiler errors anyway if
you try to call these added members (unless you use “dynamic” in C#
4.0), and so having two different views of the CLR type is OK here since
there is no scope for confusion.



This would be somewhat similar to the way C# extension methods work –
the real methods of the type get precedence, and extension methods
(comparable to monkey-patched Ruby methods) get lower precedence during
overload resolution.



Building a special mocking framework for IronRuby does not change the
basic fact that CLR types are unmodifiable. A special framework will
work only if the app is all IronRuby code, but it will break when C# is
thrown in the mix.



The current plan is to allow monkey-patching of CLR members on CLR
types. It does give power but has some unpredictability as well.
Feedback and real-world experience is welcome about whether this is the
right thing or not.



From:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Jimmy S.
Sent: Wednesday, May 13, 2009 10:03 AM

To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
Subject: Re: [Ironruby-core] more interop questions



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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Tomas M.
Sent: Wednesday, May 13, 2009 9:37 AM
To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Ivan Porto C.
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 C.

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 C.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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 C.
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_ma...  -
"Procrastination is the art of keeping up with yesterday."



_______________________________________________
Ironruby-core mailing list
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
http://rubyforge.org/mailman/listinfo/ironruby-core
Tomas M. (Guest)
on 2009-05-14 01:06
(Received via mailing list)
Yes, if the implementation uses Ruby binder for method lookup.
See RubyObject.Meta.cs for an example.

Tomas


From: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Ivan Porto
Carrero
Sent: Wednesday, May 13, 2009 1:39 PM
To: removed_email_address@domain.invalid
Subject: Re: [Ironruby-core] more interop questions

o right.. so implementing that interface on any CLR type would be enough
to make it play nice?
---
Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

Jay Leno<http://www.brainyquote.com/quotes/authors/j/jay_le...  -
"Don't forget Mother's Day. Or as they call it in Beverly Hills, Dad's
Third Wife Day."
On Wed, May 13, 2009 at 10:23 PM, Curt H.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
wrote:

You only get the dynamic behavior from C# if the actual underlying type
implements IDynamicMetaObjectProvider. In this case, Bar() returns an
object of type “System.Int32” – which does not implement that interface.



From:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Stefan D.
Sent: Wednesday, May 13, 2009 12:57 PM

To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
Subject: Re: [Ironruby-core] more interop questions



I suppose we will get the dynamic behavior if the Foo changes like this:

class Foo {

  public dynamic Bar() {

    return 42;

  }

  public void SayBar() {

    System.Console.WriteLine(Bar());

  }

}

Right?

2009/5/13 Jimmy S.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>>

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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Tomas M.
Sent: Wednesday, May 13, 2009 9:37 AM
To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>

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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Ivan Porto C.
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 C.

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 C.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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 C.
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_ma...  -
"Procrastination is the art of keeping up with yesterday."



_______________________________________________
Ironruby-core mailing list
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
http://rubyforge.org/mailman/listinfo/ironruby-core



_______________________________________________
Ironruby-core mailing list
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
http://rubyforge.org/mailman/listinfo/ironruby-core
Ivan P. (Guest)
on 2009-05-14 01:13
(Received via mailing list)
Let's just say that won't be a in a 1.0 release :)  Thanks I was quietly
hoping not to have to resort to that.
The silver lining: A push to get into COM interop and ironruby

But nailing the mocking thing right could be a huge on-ramp for ironruby
usage.. I get the feeling that most of the .NET interest comes from the
testing and silverlight integration part
---
Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

Yogi Berra <http://www.brainyquote.com/quotes/authors/y/yogi_b...
-
"If you ask me anything I don't know, I'm not going to answer."
Shri B. (Guest)
on 2009-05-14 01:22
(Received via mailing list)
The link you want is
http://msdn.microsoft.com/en-us/magazine/cc188743.aspx

From: Shri B.
Sent: Wednesday, May 13, 2009 1:58 PM
To: removed_email_address@domain.invalid
Subject: RE: [Ironruby-core] more interop questions

If you really want to push the envelope that far, you can use the
Profiling APIs (http://msdn.microsoft.com/en-us/magazine/cc300553.aspx)
to replace the IL method bodies. That will work with signed assemblies,
and you don’t need to change any source code either. Its very powerful,
but pretty complicated as well.

From: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Ivan Porto
Carrero
Sent: Wednesday, May 13, 2009 1:47 PM
To: removed_email_address@domain.invalid
Subject: Re: [Ironruby-core] more interop questions

Well actually at this point I have progressed in searching for a way to
cheat.
But I didn't find a way yet that will work with signed 3rd party signed
assemblies like say sharepoint.

I can use Mono.Cecil to change some of the types to include AOP hooks so
I can inject ruby in them and get the expected result by just not
calling the real method body. That should work for everything that isn't
signed.  if the signed assemblies aren't being referenced by anything
else than your source code then that will still work by recompiling the
source code against the new assemblies.

I think that should get me pretty far in what I'm trying to achieve with
the mocker.
I need to be able to intercept the method call, execute ruby and decide
whether or not to call the previous method.

Then I'm only stuck on how to get around 3rd party signed assemblies
with keys that I don't have access to.

In my case the expected result is when I'm working from ruby things
should behave like ruby. So if I monkey patch some method it should just
replace the thing also when C# calls it :)


---
Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

Vince
Lombardi<http://www.brainyquote.com/quotes/authors/v/vince_...
- "We didn't lose the game; we just ran out of time."
On Wed, May 13, 2009 at 9:41 PM, Shri B.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
wrote:

For the devil’s advocate position Ivan was arguing for, you could argue
that IronRuby should only allow *adding* new members to CLR types, not
to edit or delete existing CLR members. The added members would be
visible only from Ruby. From C#, you will get compiler errors anyway if
you try to call these added members (unless you use “dynamic” in C#
4.0), and so having two different views of the CLR type is OK here since
there is no scope for confusion.



This would be somewhat similar to the way C# extension methods work –
the real methods of the type get precedence, and extension methods
(comparable to monkey-patched Ruby methods) get lower precedence during
overload resolution.



Building a special mocking framework for IronRuby does not change the
basic fact that CLR types are unmodifiable. A special framework will
work only if the app is all IronRuby code, but it will break when C# is
thrown in the mix.



The current plan is to allow monkey-patching of CLR members on CLR
types. It does give power but has some unpredictability as well.
Feedback and real-world experience is welcome about whether this is the
right thing or not.



From:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Jimmy S.
Sent: Wednesday, May 13, 2009 10:03 AM

To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
Subject: Re: [Ironruby-core] more interop questions



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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Tomas M.
Sent: Wednesday, May 13, 2009 9:37 AM
To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Ivan Porto C.
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 C.

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 C.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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 C.
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_ma...  -
"Procrastination is the art of keeping up with yesterday."



_______________________________________________
Ironruby-core mailing list
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
http://rubyforge.org/mailman/listinfo/ironruby-core
Ivan P. (Guest)
on 2009-05-14 01:34
(Received via mailing list)
I am sure glad I bought the IL assembler bible a couple of weeks ago.
Thanks
a lot for the links
Stefan D. (Guest)
on 2009-05-14 01:34
(Received via mailing list)
But the call to Console.WriteLine will still be dynamic in that case.

We still need Foo to implement IDynamicMetaObjectProvider if we need the
call to Bar to be dynamic.

2009/5/13 Curt H. <removed_email_address@domain.invalid>
Curt H. (Guest)
on 2009-05-14 03:02
(Received via mailing list)
That depends on what you mean by "be dynamic"!

When the C# compiler sees the call to System.Console.WriteLine(Bar()),
it will generate a DLR call site which is bound to a C# binder that
attempts to execute the "WriteLine" function. When this code is actually
executed, the binder will look at the runtime type of the value returned
by "Bar()" and see that it has a type of System.Int32. Because this type
does not implement IDMOP, the C# binder treats it exactly as though it
were an int, and it selects the overload of WriteLine that takes a
single int argument.

When using "plain old CLR objects[1]" with the DLR, it's expected that
each language will apply its own native semantics to interactions with
those objects. C# natively has static typing, so it will always apply
static semantics to POCO. What the "dynamic" keyword means for those
objects is simply that the runtime type will be used to determine method
resolution rather than the declared compile-time type.

1: In this context, POCO is being used to refer to types that don't
implement IDMOP.

From: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Stefan D.
Sent: Wednesday, May 13, 2009 2:33 PM
To: removed_email_address@domain.invalid
Subject: Re: [Ironruby-core] more interop questions

But the call to Console.WriteLine will still be dynamic in that case.

We still need Foo to implement IDynamicMetaObjectProvider if we need the
call to Bar to be dynamic.
2009/5/13 Curt H.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>>

You only get the dynamic behavior from C# if the actual underlying type
implements IDynamicMetaObjectProvider. In this case, Bar() returns an
object of type "System.Int32" - which does not implement that interface.



From:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Stefan D.
Sent: Wednesday, May 13, 2009 12:57 PM

To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
Subject: Re: [Ironruby-core] more interop questions



I suppose we will get the dynamic behavior if the Foo changes like this:

class Foo {

  public dynamic Bar() {

    return 42;

  }

  public void SayBar() {

    System.Console.WriteLine(Bar());

  }

}

Right?

2009/5/13 Jimmy S.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>>

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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Tomas M.
Sent: Wednesday, May 13, 2009 9:37 AM
To: 
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>

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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
On Behalf Of Ivan Porto C.
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 C.

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 C.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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 C.
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_ma...  -
"Procrastination is the art of keeping up with yesterday."



_______________________________________________
Ironruby-core mailing list
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
http://rubyforge.org/mailman/listinfo/ironruby-core
Stefan D. (Guest)
on 2009-05-14 16:45
(Received via mailing list)
By dynamic I mean a CallSite is generated :)

Everything is clear to me now. Thanks.

2009/5/14 Curt H. <removed_email_address@domain.invalid>
This topic is locked and can not be replied to.