# Interop question

**URL:** <https://www.ruby-forum.com/t/interop-question/167753>\
**Category:** IronRuby\
**Created:** [May 12, 2009, 9:24am UTC](https://www.ruby-forum.com/t/interop-question/167753 "2009-05-12T09:24:37Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![barby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@barby](https://www.ruby-forum.com/u/barby)\
**Post date:** [May 12, 2009, 9:24am UTC](https://www.ruby-forum.com/t/interop-question/167753/1 "2009-05-12T09:24:37Z")

</div>

Let’s say I have these interfaces

public interface IWeapon{  
void Attack(IWarrior warrior);  
int Damage();  
}

```
public interface IWarrior
{

    int Id { get; }
    string Name { get; set; }
    bool IsKilledBy(IWeapon weapon);
    void Attack(IWarrior target, IWeapon weapon);
}

```

And one implementor defined in C#

public class Ninja : IWarrior{

```
    private readonly int _id;

    public string Name { get; set; }
    public int Id { get { return _id; } }

    public void Attack(IWarrior target, IWeapon weapon){
        weapon.Attack(target);
    }

    public bool IsKilledBy(IWeapon weapon)
    {
        return weapon.Damage() > 3;
    }
}

```

Now if I create an implementation of IWeapon in Ruby

class Shuriken

include IWeapon

def damage  
2  
end  
end

which I then proceed to wrap in a forwarding class

class ShurikenProxy

instance\_methods.each do |name|  
undef\_method name unless name =~ /^\_\_|^instance\_eval$/  
end

def initialize  
@subject = Shuriken.new  
end

def method\_missing(m, \*a, &b) @subject.send(m, \*a, &b)  
end

end

Then I would expect this to work:

ninja = Ninja.new  
ninja.is\_killed\_by ShurikenProxy.new

only it tells me that the ruby object isn’t an implementation of IWeapon  
while by all ruby standards it is. if you ask it for its ancestors it’s  
got  
IWeapon there  
if you ask it for its class it tells you Shuriken and not ShurikenProxy

Is that supposed to happen?

* * *

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

Emma Goldman  
[http://www.brainyquote.com/quotes/authors/e/emma\_goldman.html](http://www.brainyquote.com/quotes/authors/e/emma_goldman.html)

- “If voting changed anything, they’d make it illegal.”

---

<div class="post-metadata">

**Author:** ![barby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@barby](https://www.ruby-forum.com/u/barby)\
**Post date:** [May 12, 2009, 5:48pm UTC](https://www.ruby-forum.com/t/interop-question/167753/2 "2009-05-12T17:48:12Z")

</div>

Cool that’s what I figured was going on.I will have to invert the way  
I’m  
creating proxies now but that’s no problem.

* * *

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

Charles  
Kuralt[http://www.brainyquote.com/quotes/authors/c/charles\_kuralt.html](http://www.brainyquote.com/quotes/authors/c/charles_kuralt.html)

- “You can find your way across this country using burger joints the  
way a  
navigator uses stars.”

---

<div class="post-metadata">

**Author:** ![barby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@barby](https://www.ruby-forum.com/u/barby)\
**Post date:** [May 12, 2009, 10:24pm UTC](https://www.ruby-forum.com/t/interop-question/167753/3 "2009-05-12T22:24:50Z")

</div>

## About the metadata… I think in my case it would be great if I could redirect the methods on the type to methods on a property of that type. So for the ShurikenProxy class I would like to say that it needs to forward all method calls to the property subject for example possibly with an exception list of methods that won’t be forwarded. I guess that would get me the behavior I’m expecting. Would that be possible?

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

---

<div class="post-metadata">

**Author:** ![barby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@barby](https://www.ruby-forum.com/u/barby)\
**Post date:** [May 12, 2009, 4:54pm UTC](https://www.ruby-forum.com/t/interop-question/167753/4 "2009-05-12T16:54:28Z")

</div>

We canâ€™t apply all Ruby standards when we travel back to staticland.

When you define and use a Ruby class, we need to create a static CLR  
type to represent that class. This underlying type is constrained by  
what can be done with CLR types; and in particular, itâ€™s structure is  
immutable. So we canâ€™t just go back to this type and tell it that it  
should now implement IWeapon â€“ we need to have known this at the time  
the class is created.

Now, itâ€™s possible to be pretty flexible about the ingredients that go  
into the type. So if the IronRuby community decides to change how this  
underlying type is created â€“ perhaps by taking additional metadata into  
account â€“ then thatâ€™s no problem. But as soon as you create the first  
instance of ShurikenProxy, thatâ€™s when we need to freeze things and  
actually emit the type.

In this particular case, when creating a proxy for an object that  
implements certain CLR interfaces, the proxy itself will have to  
implement the same interfaces if the object is going to be passed back  
to static code. But Rubyâ€™s metaprogramming makes this pretty easy â€“ get  
all ancestors of class Module whose to\_clr\_type is not nil, and simply  
include those into a newly-created proxy class programmatically.

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Ivan Porto  
Carrero  
Sent: Tuesday, May 12, 2009 12:23 AM  
To: ironruby-core  
Subject: [Ironruby-core] interop question

Let’s say I have these interfaces

public interface IWeapon{  
void Attack(IWarrior warrior);  
int Damage();  
}

```
public interface IWarrior
{

    int Id { get; }
    string Name { get; set; }
    bool IsKilledBy(IWeapon weapon);
    void Attack(IWarrior target, IWeapon weapon);
}

```

And one implementor defined in C#

public class Ninja : IWarrior{

```
    private readonly int _id;

    public string Name { get; set; }
    public int Id { get { return _id; } }

    public void Attack(IWarrior target, IWeapon weapon){
        weapon.Attack(target);
    }

    public bool IsKilledBy(IWeapon weapon)
    {
        return weapon.Damage() > 3;
    }
}

```

Now if I create an implementation of IWeapon in Ruby

class Shuriken

include IWeapon

def damage  
2  
end  
end

which I then proceed to wrap in a forwarding class

class ShurikenProxy

instance\_methods.each do |name|  
undef\_method name unless name =~ /^\_\_|^instance\_eval$/  
end

def initialize  
@subject = Shuriken.new  
end

def method\_missing(m, \*a, &b)  
@subject.send(m, \*a, &b)  
end

end

Then I would expect this to work:

ninja = Ninja.new  
ninja.is\_killed\_by ShurikenProxy.new

only it tells me that the ruby object isn’t an implementation of IWeapon  
while by all ruby standards it is. if you ask it for its ancestors it’s  
got IWeapon there  
if you ask it for its class it tells you Shuriken and not ShurikenProxy

Is that supposed to happen?

* * *

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

Emma  
Goldman[http://www.brainyquote.com/quotes/authors/e/emma\_goldman.html](http://www.brainyquote.com/quotes/authors/e/emma_goldman.html)

- “If voting changed anything, they’d make it illegal.”

---

<div class="post-metadata">

**Author:** ![barby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@barby](https://www.ruby-forum.com/u/barby)\
**Post date:** [May 12, 2009, 10:44pm UTC](https://www.ruby-forum.com/t/interop-question/167753/5 "2009-05-12T22:44:53Z")

</div>

But this redirection can be done entirely at the level of Ruby  
metaprogramming, canâ€™t it. Iâ€™m pretty sure Iâ€™ve seen Proxy objects  
defined in ActiveSupport that do something quite similar. (Full  
disclosure, though: Iâ€™m really a Ruby noob.)

By contrast, consider the following

class C  
clr\_property :Value, System::Int32, ::get\_value, ::set\_value

def get\_value  
42  
end  
def set\_value  
raise RuntimeError, ‘Read-only, sucker!’  
end  
end

The hypothetical class method clr\_property might set some kind of  
metadata on the class which would be picked up by the CLS type  
generator, and turned into a CLS-visible property on the generated type  
with getter and setter methods. This is the sort of thing I had in mind  
when I described â€œadditional metadataâ€.

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Ivan Porto  
Carrero  
Sent: Tuesday, May 12, 2009 12:58 PM  
To: removed\_email\_address@domain.invalid  
Subject: Re: [Ironruby-core] interop question

About the metadata… I think in my case it would be great if I could  
redirect the methods on the type to methods on a property of that type.

## So for the ShurikenProxy class I would like to say that it needs to forward all method calls to the property subject for example possibly with an exception list of methods that won’t be forwarded. I guess that would get me the behavior I’m expecting. Would that be possible?

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

On Tue, May 12, 2009 at 4:49 PM, Curt H.  
\<removed\_email\_address@domain.invalid[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)\> wrote:

We canâ€™t apply all Ruby standards when we travel back to staticland.

When you define and use a Ruby class, we need to create a static CLR  
type to represent that class. This underlying type is constrained by  
what can be done with CLR types; and in particular, itâ€™s structure is  
immutable. So we canâ€™t just go back to this type and tell it that it  
should now implement IWeapon â€“ we need to have known this at the time  
the class is created.

Now, itâ€™s possible to be pretty flexible about the ingredients that go  
into the type. So if the IronRuby community decides to change how this  
underlying type is created â€“ perhaps by taking additional metadata into  
account â€“ then thatâ€™s no problem. But as soon as you create the first  
instance of ShurikenProxy, thatâ€™s when we need to freeze things and  
actually emit the type.

In this particular case, when creating a proxy for an object that  
implements certain CLR interfaces, the proxy itself will have to  
implement the same interfaces if the object is going to be passed back  
to static code. But Rubyâ€™s metaprogramming makes this pretty easy â€“ get  
all ancestors of class Module whose to\_clr\_type is not nil, and simply  
include those into a newly-created proxy class programmatically.

From:  
removed\_email\_address@domain.invalid[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
[[mailto: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: Tuesday, May 12, 2009 12:23 AM  
To: ironruby-core  
Subject: [Ironruby-core] interop question

Let’s say I have these interfaces

public interface IWeapon{

```
    void Attack(IWarrior warrior);

    int Damage();

}

public interface IWarrior

{

    int Id { get; }

    string Name { get; set; }

    bool IsKilledBy(IWeapon weapon);

    void Attack(IWarrior target, IWeapon weapon);

}

```

And one implementor defined in C#

public class Ninja : IWarrior{

```
    private readonly int _id;

    public string Name { get; set; }

    public int Id { get { return _id; } }

    public void Attack(IWarrior target, IWeapon weapon){

        weapon.Attack(target);

    }

    public bool IsKilledBy(IWeapon weapon)

    {

        return weapon.Damage() > 3;

    }

}

```

Now if I create an implementation of IWeapon in Ruby

class Shuriken

include IWeapon

def damage

```
  2

```

end

end

which I then proceed to wrap in a forwarding class

class ShurikenProxy

instance\_methods.each do |name|

```
  undef_method name unless name =~ /^__|^instance_eval$/

end

```

def initialize

```
  @subject = Shuriken.new

```

end

def method\_missing(m, \*a, &b)

```
 @subject.send(m, *a, &b)

```

end

end

Then I would expect this to work:

ninja = Ninja.new

ninja.is\_killed\_by ShurikenProxy.new

only it tells me that the ruby object isn’t an implementation of IWeapon

while by all ruby standards it is. if you ask it for its ancestors it’s  
got IWeapon there

if you ask it for its class it tells you Shuriken and not ShurikenProxy

Is that supposed to happen?

* * *

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

Emma  
Goldman[http://www.brainyquote.com/quotes/authors/e/emma\_goldman.html](http://www.brainyquote.com/quotes/authors/e/emma_goldman.html)

- “If voting changed anything, they’d make it illegal.”

* * *

Ironruby-core mailing list  
removed\_email\_address@domain.invalid[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
[http://rubyforge.org/mailman/listinfo/ironruby-core](http://rubyforge.org/mailman/listinfo/ironruby-core)

---

<div class="post-metadata">

**Author:** ![barby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@barby](https://www.ruby-forum.com/u/barby)\
**Post date:** [May 12, 2009, 10:57pm UTC](https://www.ruby-forum.com/t/interop-question/167753/6 "2009-05-12T22:57:48Z")

</div>

## That would be great for databinding wpf 🙂

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

Vince  
Lombardi[http://www.brainyquote.com/quotes/authors/v/vince\_lombardi.html](http://www.brainyquote.com/quotes/authors/v/vince_lombardi.html)

- “We didn’t lose the game; we just ran out of time.”
