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 Carrero Blog: http://flanders.co.nz Twitter: http://twitter.com/casualjim Author of IronRuby in Action (http://manning.com/carrero) Emma Goldman <http://www.brainyquote.com/quotes/authors/e/emma_goldman.html> - "If voting changed anything, they''d make it illegal." -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20090512/bcafaa61/attachment.html>
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: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] 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 Carrero Blog: http://flanders.co.nz Twitter: http://twitter.com/casualjim Author of IronRuby in Action (http://manning.com/carrero) Emma Goldman<http://www.brainyquote.com/quotes/authors/e/emma_goldman.html> - "If voting changed anything, they''d make it illegal." -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20090512/621482fb/attachment.html>
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 Carrero Blog: http://flanders.co.nz Twitter: http://twitter.com/casualjim Author of IronRuby in Action (http://manning.com/carrero) Charles Kuralt<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." On Tue, May 12, 2009 at 4:49 PM, Curt Hagenlocher <curth at microsoft.com>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:* ironruby-core-bounces at rubyforge.org [mailto: > ironruby-core-bounces at rubyforge.org] *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 Carrero > Blog: http://flanders.co.nz > Twitter: http://twitter.com/casualjim > Author of IronRuby in Action (http://manning.com/carrero) > > Emma Goldman<http://www.brainyquote.com/quotes/authors/e/emma_goldman.html> - "If voting changed anything, they''d make it illegal." > > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20090512/01ea1bfb/attachment.html>
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 Carrero Blog: http://flanders.co.nz Twitter: http://twitter.com/casualjim Author of IronRuby in Action (http://manning.com/carrero) On Tue, May 12, 2009 at 4:49 PM, Curt Hagenlocher <curth at microsoft.com>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:* ironruby-core-bounces at rubyforge.org [mailto: > ironruby-core-bounces at rubyforge.org] *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 Carrero > Blog: http://flanders.co.nz > Twitter: http://twitter.com/casualjim > Author of IronRuby in Action (http://manning.com/carrero) > > Emma Goldman<http://www.brainyquote.com/quotes/authors/e/emma_goldman.html> - "If voting changed anything, they''d make it illegal." > > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20090512/a89f0083/attachment.html>
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: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Ivan Porto Carrero Sent: Tuesday, May 12, 2009 12:58 PM To: ironruby-core at rubyforge.org 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 Carrero Blog: http://flanders.co.nz Twitter: http://twitter.com/casualjim Author of IronRuby in Action (http://manning.com/carrero) On Tue, May 12, 2009 at 4:49 PM, Curt Hagenlocher <curth at microsoft.com<mailto:curth at microsoft.com>> 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: ironruby-core-bounces at rubyforge.org<mailto:ironruby-core-bounces at rubyforge.org> [mailto:ironruby-core-bounces at rubyforge.org<mailto:ironruby-core-bounces at rubyforge.org>] 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 Carrero Blog: http://flanders.co.nz Twitter: http://twitter.com/casualjim Author of IronRuby in Action (http://manning.com/carrero) Emma Goldman<http://www.brainyquote.com/quotes/authors/e/emma_goldman.html> - "If voting changed anything, they''d make it illegal." _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org<mailto:Ironruby-core at rubyforge.org> http://rubyforge.org/mailman/listinfo/ironruby-core -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20090512/5753f99b/attachment.html>
That would be great for databinding wpf :) --- 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) Vince Lombardi<http://www.brainyquote.com/quotes/authors/v/vince_lombardi.html> - "We didn''t lose the game; we just ran out of time." On Tue, May 12, 2009 at 10:35 PM, Curt Hagenlocher <curth at microsoft.com>wrote:> 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:* ironruby-core-bounces at rubyforge.org [mailto: > ironruby-core-bounces at rubyforge.org] *On Behalf Of *Ivan Porto Carrero > *Sent:* Tuesday, May 12, 2009 12:58 PM > *To:* ironruby-core at rubyforge.org > *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 Carrero > Blog: http://flanders.co.nz > Twitter: http://twitter.com/casualjim > Author of IronRuby in Action (http://manning.com/carrero) > > On Tue, May 12, 2009 at 4:49 PM, Curt Hagenlocher <curth at microsoft.com> > 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:* ironruby-core-bounces at rubyforge.org [mailto: > ironruby-core-bounces at rubyforge.org] *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 Carrero > Blog: http://flanders.co.nz > Twitter: http://twitter.com/casualjim > Author of IronRuby in Action (http://manning.com/carrero) > > Emma Goldman<http://www.brainyquote.com/quotes/authors/e/emma_goldman.html> - "If voting changed anything, they''d make it illegal." > > > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > > > > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20090512/2cc556b3/attachment.html>