Why does attr_accessor create a property, but method is just a method?

This is a cross-post from Stack Overflow, but I haven’t heard a peep
there,
so I figured I’d try here:

I am playing around with the interop between C# and IronRuby. I have
noticed that if I define a property in Ruby using attr_accessor, it is
presented to C# as a property. If, on the other hand, I create the
exact
same code manually, it comes back as a method.

For example, take this code:

var engine = IronRuby.Ruby.CreateEngine();
string script = @"
  class Test
    attr_accessor :automatic

    def manual
      @manual
    end

    def manual=(val)
      @manual = val
    end

    def initialize
      @automatic = ""testing""
      @manual = ""testing""
    end
  end

  Test.new
";
var testObject = engine.Execute(script);

var automatic = testObject.automatic;
var manual = testObject.manual;

When you look at the C# automatic variable, the value is a string of
“testing”. If you look at the C# manual variable, it is type
IronRuby.Builtins.RubyMethod.

Ultimately, I want to create my own properties in Ruby that can be used
in
C#, but I can’t seem to make them be visible as properties like
attr_accessor does.

I THINK, that there is some magic going on in the Module code of the
Ruby
source code (ModuleOps.cs:DefineAccessor). Is there any way to do this
in
Ruby code directly?

Thanks,
Brian

So, I haven’t heard anything about this yet on Stack Overflow, or this
list.

Does anyone know if this is this a bug in IronRuby interop?

Thanks,
Brian

I believe this works as designed.

The problem is that Ruby doesn’t otherwise distinguish syntactically
between a property and a method with no parameters. Imagine that you’re
in tooling such as Visual Studio. By default, the values of properties
are automatically displayed in the debugger and in tool tips. But if I
happen to have a no-args method named format_cdrive, I probably don’t
want that code to be run just to inspect its value. Effectively,
attr_accessor, attr_reader and attr_writer are used by IronRuby as
signals that indicate this operation is free of potentially-nasty side
effects.

From: [email protected]
[mailto:[email protected]] On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 5:49 AM
To: [email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

So, I haven’t heard anything about this yet on Stack Overflow, or this
list.

Does anyone know if this is this a bug in IronRuby interop?
Thanks,
Brian

On Wed, Jul 21, 2010 at 12:34 PM, Brian G.
<[email protected]mailto:[email protected]> wrote:
This is a cross-post from Stack Overflow, but I haven’t heard a peep
there, so I figured I’d try here:

I am playing around with the interop between C# and IronRuby. I have
noticed that if I define a property in Ruby using attr_accessor, it is
presented to C# as a property. If, on the other hand, I create the
exact same code manually, it comes back as a method.

For example, take this code:

var engine = IronRuby.Ruby.CreateEngine();
string script = @"
  class Test
    attr_accessor :automatic

    def manual
      @manual
    end

    def manual=(val)
      @manual = val
    end

    def initialize
      @automatic = ""testing""
      @manual = ""testing""
    end
  end

  Test.new
";
var testObject = engine.Execute(script);

var automatic = testObject.automatic;
var manual = testObject.manual;

When you look at the C# automatic variable, the value is a string of
“testing”. If you look at the C# manual variable, it is type
IronRuby.Builtins.RubyMethod.

Ultimately, I want to create my own properties in Ruby that can be used
in C#, but I can’t seem to make them be visible as properties like
attr_accessor does.

I THINK, that there is some magic going on in the Module code of the
Ruby source code (ModuleOps.cs:DefineAccessor). Is there any way to do
this in Ruby code directly?

Thanks,
Brian

Curt,

Thank you very much for engaging :slight_smile:

Although I understand what you are saying, from an interop perspective,
this
is not desirable.

In fact, the WPF binding system will see two methods (foo and foo=(val))
and
determine that they are properties that can be bound to. C#, on the
other
hand, can’t use them as properties. Furthermore, if I want a simple
side
effect (like property change notification) in a property, it makes sense
for
me to define my own foo and foo=(val) methods. Again, WPF can get these
notifications and read the “properties”, but C# just sees methods.
Another
case might be where properties are just wrappers around hashes… a case
I
am running into.

At a very minimum, I would expect to be able to create get_foo and
set_foo(value) in ruby to have them be seen as .Net properties, but this
doesn’t seem to work either.

In general, I am trying to understand good interop practices between my
ruby
and C# and WPF code, but I can’t seem to make anything other than
attr_accessor work.

Brian

Thinking on this further, if there were some sort of interop-specific
class
method… like attr_clr_property :foo, that caused any methods named foo
and
foo=(var) to be visible to .Net as properties, that would be sufficient.

Any thoughts on this?
B

WPF binds by effectively treating the Ruby object as “dynamic” - that
is, it goes through IDynamicMetaObjectProvider. You can get the same
behavior from C# by saying

dynamic obj = SomeRubyObject();
dynamic foo = obj.foo;

Is this not sufficient for your needs?

From: [email protected]
[mailto:[email protected]] On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 6:55 AM
To: [email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

Thinking on this further, if there were some sort of interop-specific
class method… like attr_clr_property :foo, that caused any methods
named foo and foo=(var) to be visible to .Net as properties, that would
be sufficient.

Any thoughts on this?
B
On Thu, Jul 22, 2010 at 9:34 AM, Brian G.
<[email protected]mailto:[email protected]> wrote:
Curt,

Thank you very much for engaging :slight_smile:

Although I understand what you are saying, from an interop perspective,
this is not desirable.

In fact, the WPF binding system will see two methods (foo and foo=(val))
and determine that they are properties that can be bound to. C#, on the
other hand, can’t use them as properties. Furthermore, if I want a
simple side effect (like property change notification) in a property, it
makes sense for me to define my own foo and foo=(val) methods. Again,
WPF can get these notifications and read the “properties”, but C# just
sees methods. Another case might be where properties are just wrappers
around hashes… a case I am running into.

At a very minimum, I would expect to be able to create get_foo and
set_foo(value) in ruby to have them be seen as .Net properties, but this
doesn’t seem to work either.

In general, I am trying to understand good interop practices between my
ruby and C# and WPF code, but I can’t seem to make anything other than
attr_accessor work.

Brian
On Thu, Jul 22, 2010 at 9:17 AM, Curt H.
<[email protected]mailto:[email protected]> wrote:
I believe this works as designed.

The problem is that Ruby doesn’t otherwise distinguish syntactically
between a property and a method with no parameters. Imagine that you’re
in tooling such as Visual Studio. By default, the values of properties
are automatically displayed in the debugger and in tool tips. But if I
happen to have a no-args method named format_cdrive, I probably don’t
want that code to be run just to inspect its value. Effectively,
attr_accessor, attr_reader and attr_writer are used by IronRuby as
signals that indicate this operation is free of potentially-nasty side
effects.

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 5:49 AM
To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

So, I haven’t heard anything about this yet on Stack Overflow, or this
list.

Does anyone know if this is this a bug in IronRuby interop?
Thanks,
Brian

On Wed, Jul 21, 2010 at 12:34 PM, Brian G.
<[email protected]mailto:[email protected]> wrote:
This is a cross-post from Stack Overflow, but I haven’t heard a peep
there, so I figured I’d try here:

I am playing around with the interop between C# and IronRuby. I have
noticed that if I define a property in Ruby using attr_accessor, it is
presented to C# as a property. If, on the other hand, I create the
exact same code manually, it comes back as a method.

For example, take this code:

var engine = IronRuby.Ruby.CreateEngine();
string script = @"
  class Test
    attr_accessor :automatic

    def manual
      @manual
    end

    def manual=(val)
      @manual = val
    end

    def initialize
      @automatic = ""testing""
      @manual = ""testing""
    end
  end

  Test.new
";
var testObject = engine.Execute(script);

var automatic = testObject.automatic;
var manual = testObject.manual;

When you look at the C# automatic variable, the value is a string of
“testing”. If you look at the C# manual variable, it is type
IronRuby.Builtins.RubyMethod.

Ultimately, I want to create my own properties in Ruby that can be used
in C#, but I can’t seem to make them be visible as properties like
attr_accessor does.

I THINK, that there is some magic going on in the Module code of the
Ruby source code (ModuleOps.cs:DefineAccessor). Is there any way to do
this in Ruby code directly?

Thanks,
Brian

No, that is not sufficient, because it does not work. Assuming the
example
I posted, this code fails:

dynamic automatic = testObject.automatic;
dynamic manual = testObject.manual;

dynamic autoLength = automatic.Length;
dynamic manualLength = manual.Length; // RuntimeBinderException

manual.Length fails because manual is of type
IronRuby.Builtins.RubyMethod and Length is not defined.

This is my problem… since ‘manual’ is not exposed to .Net as a
property,
it fails.

Brian

P.S. I REALLY appreciate you talking through this with me.

I don’t know that you should appreciate anything I say; I haven’t worked
on IronRuby in over a year. :smiley:

A long time ago, I wrote code for ICustomTypeDescriptor that does
property inference based on the presence of arity-0 “foo” and arity-1
“foo=” but I had assumed that WPF was now binding via IDMOP and not
ICustomTypeDescriptor. Since this doesn’t work via “dynamic”, I guess
that’s not the case. Maybe Tomáš has something to add?

From: [email protected]
[mailto:[email protected]] On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 7:10 AM
To: [email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

No, that is not sufficient, because it does not work. Assuming the
example I posted, this code fails:

dynamic automatic = testObject.automatic;
dynamic manual = testObject.manual;

dynamic autoLength = automatic.Length;
dynamic manualLength = manual.Length; // RuntimeBinderException

manual.Length fails because manual is of type
IronRuby.Builtins.RubyMethod and Length is not defined.

This is my problem… since ‘manual’ is not exposed to .Net as a
property, it fails.

Brian

P.S. I REALLY appreciate you talking through this with me.

On Thu, Jul 22, 2010 at 10:01 AM, Curt H.
<[email protected]mailto:[email protected]> wrote:
WPF binds by effectively treating the Ruby object as “dynamic” - that
is, it goes through IDynamicMetaObjectProvider. You can get the same
behavior from C# by saying

dynamic obj = SomeRubyObject();
dynamic foo = obj.foo;

Is this not sufficient for your needs?

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 6:55 AM

To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

Thinking on this further, if there were some sort of interop-specific
class method… like attr_clr_property :foo, that caused any methods
named foo and foo=(var) to be visible to .Net as properties, that would
be sufficient.

Any thoughts on this?
B
On Thu, Jul 22, 2010 at 9:34 AM, Brian G.
<[email protected]mailto:[email protected]> wrote:
Curt,

Thank you very much for engaging :slight_smile:

Although I understand what you are saying, from an interop perspective,
this is not desirable.

In fact, the WPF binding system will see two methods (foo and foo=(val))
and determine that they are properties that can be bound to. C#, on the
other hand, can’t use them as properties. Furthermore, if I want a
simple side effect (like property change notification) in a property, it
makes sense for me to define my own foo and foo=(val) methods. Again,
WPF can get these notifications and read the “properties”, but C# just
sees methods. Another case might be where properties are just wrappers
around hashes… a case I am running into.

At a very minimum, I would expect to be able to create get_foo and
set_foo(value) in ruby to have them be seen as .Net properties, but this
doesn’t seem to work either.

In general, I am trying to understand good interop practices between my
ruby and C# and WPF code, but I can’t seem to make anything other than
attr_accessor work.

Brian
On Thu, Jul 22, 2010 at 9:17 AM, Curt H.
<[email protected]mailto:[email protected]> wrote:
I believe this works as designed.

The problem is that Ruby doesn’t otherwise distinguish syntactically
between a property and a method with no parameters. Imagine that you’re
in tooling such as Visual Studio. By default, the values of properties
are automatically displayed in the debugger and in tool tips. But if I
happen to have a no-args method named format_cdrive, I probably don’t
want that code to be run just to inspect its value. Effectively,
attr_accessor, attr_reader and attr_writer are used by IronRuby as
signals that indicate this operation is free of potentially-nasty side
effects.

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 5:49 AM
To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

So, I haven’t heard anything about this yet on Stack Overflow, or this
list.

Does anyone know if this is this a bug in IronRuby interop?
Thanks,
Brian

On Wed, Jul 21, 2010 at 12:34 PM, Brian G.
<[email protected]mailto:[email protected]> wrote:
This is a cross-post from Stack Overflow, but I haven’t heard a peep
there, so I figured I’d try here:

I am playing around with the interop between C# and IronRuby. I have
noticed that if I define a property in Ruby using attr_accessor, it is
presented to C# as a property. If, on the other hand, I create the
exact same code manually, it comes back as a method.

For example, take this code:

var engine = IronRuby.Ruby.CreateEngine();
string script = @"
  class Test
    attr_accessor :automatic

    def manual
      @manual
    end

    def manual=(val)
      @manual = val
    end

    def initialize
      @automatic = ""testing""
      @manual = ""testing""
    end
  end

  Test.new
";
var testObject = engine.Execute(script);

var automatic = testObject.automatic;
var manual = testObject.manual;

When you look at the C# automatic variable, the value is a string of
“testing”. If you look at the C# manual variable, it is type
IronRuby.Builtins.RubyMethod.

Ultimately, I want to create my own properties in Ruby that can be used
in C#, but I can’t seem to make them be visible as properties like
attr_accessor does.

I THINK, that there is some magic going on in the Module code of the
Ruby source code (ModuleOps.cs:DefineAccessor). Is there any way to do
this in Ruby code directly?

Thanks,
Brian


Ironruby-core mailing list
[email protected]mailto:[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core

Awesome! Do you take patches from the community?

Thanks,
Brian

2010/7/22 Tomas M. [email protected]

Ability to mark an existing method (pair) as a “property” implementation
makes sense.
I’ve added it the feature list:
http://ironruby.codeplex.com/workitem/4920

Tomas

From: [email protected]
[mailto:[email protected]] On Behalf Of Curt
Hagenlocher
Sent: Thursday, July 22, 2010 7:19 AM
To: [email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

I don’t know that you should appreciate anything I say; I haven’t worked
on IronRuby in over a year. :smiley:

A long time ago, I wrote code for ICustomTypeDescriptor that does
property inference based on the presence of arity-0 “foo” and arity-1
“foo=” but I had assumed that WPF was now binding via IDMOP and not
ICustomTypeDescriptor. Since this doesn’t work via “dynamic”, I guess
that’s not the case. Maybe Tomáš has something to add?

From: [email protected]
[mailto:[email protected]] On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 7:10 AM
To: [email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

No, that is not sufficient, because it does not work. Assuming the
example I posted, this code fails:

dynamic automatic = testObject.automatic;
dynamic manual = testObject.manual;

dynamic autoLength = automatic.Length;
dynamic manualLength = manual.Length; // RuntimeBinderException

manual.Length fails because manual is of type
IronRuby.Builtins.RubyMethod and Length is not defined.

This is my problem… since ‘manual’ is not exposed to .Net as a
property, it fails.

Brian

P.S. I REALLY appreciate you talking through this with me.

On Thu, Jul 22, 2010 at 10:01 AM, Curt H.
<[email protected]mailto:[email protected]> wrote:
WPF binds by effectively treating the Ruby object as “dynamic” - that
is, it goes through IDynamicMetaObjectProvider. You can get the same
behavior from C# by saying

dynamic obj = SomeRubyObject();
dynamic foo = obj.foo;

Is this not sufficient for your needs?

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 6:55 AM

To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

Thinking on this further, if there were some sort of interop-specific
class method… like attr_clr_property :foo, that caused any methods
named foo and foo=(var) to be visible to .Net as properties, that would
be sufficient.

Any thoughts on this?
B
On Thu, Jul 22, 2010 at 9:34 AM, Brian G.
<[email protected]mailto:[email protected]> wrote:
Curt,

Thank you very much for engaging :slight_smile:

Although I understand what you are saying, from an interop perspective,
this is not desirable.

In fact, the WPF binding system will see two methods (foo and foo=(val))
and determine that they are properties that can be bound to. C#, on the
other hand, can’t use them as properties. Furthermore, if I want a
simple side effect (like property change notification) in a property, it
makes sense for me to define my own foo and foo=(val) methods. Again,
WPF can get these notifications and read the “properties”, but C# just
sees methods. Another case might be where properties are just wrappers
around hashes… a case I am running into.

At a very minimum, I would expect to be able to create get_foo and
set_foo(value) in ruby to have them be seen as .Net properties, but this
doesn’t seem to work either.

In general, I am trying to understand good interop practices between my
ruby and C# and WPF code, but I can’t seem to make anything other than
attr_accessor work.

Brian
On Thu, Jul 22, 2010 at 9:17 AM, Curt H.
<[email protected]mailto:[email protected]> wrote:
I believe this works as designed.

The problem is that Ruby doesn’t otherwise distinguish syntactically
between a property and a method with no parameters. Imagine that you’re
in tooling such as Visual Studio. By default, the values of properties
are automatically displayed in the debugger and in tool tips. But if I
happen to have a no-args method named format_cdrive, I probably don’t
want that code to be run just to inspect its value. Effectively,
attr_accessor, attr_reader and attr_writer are used by IronRuby as
signals that indicate this operation is free of potentially-nasty side
effects.

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 5:49 AM
To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

So, I haven’t heard anything about this yet on Stack Overflow, or this
list.

Does anyone know if this is this a bug in IronRuby interop?
Thanks,
Brian

On Wed, Jul 21, 2010 at 12:34 PM, Brian G.
<[email protected]mailto:[email protected]> wrote:
This is a cross-post from Stack Overflow, but I haven’t heard a peep
there, so I figured I’d try here:

I am playing around with the interop between C# and IronRuby. I have
noticed that if I define a property in Ruby using attr_accessor, it is
presented to C# as a property. If, on the other hand, I create the
exact same code manually, it comes back as a method.

For example, take this code:

var engine = IronRuby.Ruby.CreateEngine();
string script = @"
  class Test
    attr_accessor :automatic

    def manual
      @manual
    end

    def manual=(val)
      @manual = val
    end

    def initialize
      @automatic = ""testing""
      @manual = ""testing""
    end
  end

  Test.new
";
var testObject = engine.Execute(script);

var automatic = testObject.automatic;
var manual = testObject.manual;

When you look at the C# automatic variable, the value is a string of
“testing”. If you look at the C# manual variable, it is type
IronRuby.Builtins.RubyMethod.

Ultimately, I want to create my own properties in Ruby that can be used
in C#, but I can’t seem to make them be visible as properties like
attr_accessor does.

I THINK, that there is some magic going on in the Module code of the
Ruby source code (ModuleOps.cs:DefineAccessor). Is there any way to do
this in Ruby code directly?

Thanks,
Brian


Ironruby-core mailing list
[email protected]mailto:[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core

Brian G. wrote:

Thinking on this further, if there were some sort of interop-specific class
method… like attr_clr_property :foo, that caused any methods named foo and
foo=(var) to be visible to .Net as properties, that would be sufficient.

Any thoughts on this?

Alternative suggestion: make method redefinition work in this case,
like this:

var engine = IronRuby.Ruby.CreateEngine();
var script = @"
    class Test
      attr_accessor :a, :m

      def m; @m end
      def m=(val) @m = val end

      def initialize; @a, @m = 'automatic', 'manual' end
    end

    Test.new
";
var testObject = engine.Execute(script);

var automatic = testObject.a;
var manual = testObject.m;

Console.WriteLine(automatic);
Console.WriteLine(manual);    // should print "manual"
Console.ReadLine();

jwm

Absolutely.

Tomas

From: [email protected]
[mailto:[email protected]] On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 11:50 AM
To: [email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

Awesome! Do you take patches from the community?

Thanks,
Brian
2010/7/22 Tomas M.
<[email protected]mailto:[email protected]>
Ability to mark an existing method (pair) as a “property” implementation
makes sense.
I’ve added it the feature list:
http://ironruby.codeplex.com/workitem/4920

Tomas

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Curt H.
Sent: Thursday, July 22, 2010 7:19 AM

To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

I don’t know that you should appreciate anything I say; I haven’t worked
on IronRuby in over a year. :smiley:

A long time ago, I wrote code for ICustomTypeDescriptor that does
property inference based on the presence of arity-0 “foo” and arity-1
“foo=” but I had assumed that WPF was now binding via IDMOP and not
ICustomTypeDescriptor. Since this doesn’t work via “dynamic”, I guess
that’s not the case. Maybe Tomáš has something to add?

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 7:10 AM
To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

No, that is not sufficient, because it does not work. Assuming the
example I posted, this code fails:

dynamic automatic = testObject.automatic;
dynamic manual = testObject.manual;

dynamic autoLength = automatic.Length;
dynamic manualLength = manual.Length; // RuntimeBinderException

manual.Length fails because manual is of type
IronRuby.Builtins.RubyMethod and Length is not defined.

This is my problem… since ‘manual’ is not exposed to .Net as a
property, it fails.

Brian

P.S. I REALLY appreciate you talking through this with me.

On Thu, Jul 22, 2010 at 10:01 AM, Curt H.
<[email protected]mailto:[email protected]> wrote:
WPF binds by effectively treating the Ruby object as “dynamic” - that
is, it goes through IDynamicMetaObjectProvider. You can get the same
behavior from C# by saying

dynamic obj = SomeRubyObject();
dynamic foo = obj.foo;

Is this not sufficient for your needs?

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 6:55 AM

To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

Thinking on this further, if there were some sort of interop-specific
class method… like attr_clr_property :foo, that caused any methods
named foo and foo=(var) to be visible to .Net as properties, that would
be sufficient.

Any thoughts on this?
B
On Thu, Jul 22, 2010 at 9:34 AM, Brian G.
<[email protected]mailto:[email protected]> wrote:
Curt,

Thank you very much for engaging :slight_smile:

Although I understand what you are saying, from an interop perspective,
this is not desirable.

In fact, the WPF binding system will see two methods (foo and foo=(val))
and determine that they are properties that can be bound to. C#, on the
other hand, can’t use them as properties. Furthermore, if I want a
simple side effect (like property change notification) in a property, it
makes sense for me to define my own foo and foo=(val) methods. Again,
WPF can get these notifications and read the “properties”, but C# just
sees methods. Another case might be where properties are just wrappers
around hashes… a case I am running into.

At a very minimum, I would expect to be able to create get_foo and
set_foo(value) in ruby to have them be seen as .Net properties, but this
doesn’t seem to work either.

In general, I am trying to understand good interop practices between my
ruby and C# and WPF code, but I can’t seem to make anything other than
attr_accessor work.

Brian
On Thu, Jul 22, 2010 at 9:17 AM, Curt H.
<[email protected]mailto:[email protected]> wrote:
I believe this works as designed.

The problem is that Ruby doesn’t otherwise distinguish syntactically
between a property and a method with no parameters. Imagine that you’re
in tooling such as Visual Studio. By default, the values of properties
are automatically displayed in the debugger and in tool tips. But if I
happen to have a no-args method named format_cdrive, I probably don’t
want that code to be run just to inspect its value. Effectively,
attr_accessor, attr_reader and attr_writer are used by IronRuby as
signals that indicate this operation is free of potentially-nasty side
effects.

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Brian G.
Sent: Thursday, July 22, 2010 5:49 AM
To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Why does attr_accessor create a property,
but method is just a method?

So, I haven’t heard anything about this yet on Stack Overflow, or this
list.

Does anyone know if this is this a bug in IronRuby interop?
Thanks,
Brian

On Wed, Jul 21, 2010 at 12:34 PM, Brian G.
<[email protected]mailto:[email protected]> wrote:
This is a cross-post from Stack Overflow, but I haven’t heard a peep
there, so I figured I’d try here:

I am playing around with the interop between C# and IronRuby. I have
noticed that if I define a property in Ruby using attr_accessor, it is
presented to C# as a property. If, on the other hand, I create the
exact same code manually, it comes back as a method.

For example, take this code:

var engine = IronRuby.Ruby.CreateEngine();
string script = @"
  class Test
    attr_accessor :automatic

    def manual
      @manual
    end

    def manual=(val)
      @manual = val
    end

    def initialize
      @automatic = ""testing""
      @manual = ""testing""
    end
  end

  Test.new
";
var testObject = engine.Execute(script);

var automatic = testObject.automatic;
var manual = testObject.manual;

When you look at the C# automatic variable, the value is a string of
“testing”. If you look at the C# manual variable, it is type
IronRuby.Builtins.RubyMethod.

Ultimately, I want to create my own properties in Ruby that can be used
in C#, but I can’t seem to make them be visible as properties like
attr_accessor does.

I THINK, that there is some magic going on in the Module code of the
Ruby source code (ModuleOps.cs:DefineAccessor). Is there any way to do
this in Ruby code directly?

Thanks,
Brian


Ironruby-core mailing list
[email protected]mailto:[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core


Ironruby-core mailing list
[email protected]mailto:[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core

Brian G. wrote:

Thinking on this further, if there were some sort of interop-specific class
method… like attr_clr_property :foo, that caused any methods named foo and
foo=(var) to be visible to .Net as properties, that would be sufficient.

Any thoughts on this?

Good idea. Would it make sense to coordinate with other
implementations to get some more generic name and semantics?
Objective-C (and thus MacRuby) also has a notion of properties, right?
As do JavaBeans.

What about

Module#prop_accessor
Module#prop_getter
Module#prop_setter

That way, if I have a simple PORO/POCO/POJO that I want to be able to
interoperate with platform-native code, I only need to switch out
require ‘clr’ for require ‘java’, but not change any of my other code.
(Assuming, of course, that the only .NET-specific stuff in my code are
properties.)

jwm

Yes, this is one approached I’ve considered.

What about this case?

    class Test
      attr_accessor :a, :m
    end

    class Test2 < Test
      def m; @m end
      def m=(val) @m = val end

      def initialize; @a, @m = 'automatic', 'manual' end
    end

And this one?

    class Test
      attr_accessor :a, :m
      include M
    end

    class Test2
      include M
    end

    module M
      def m; @m end        # should this be a property accessor or 

not?
def m=(val) @m = val end

      def initialize; @a, @m = 'automatic', 'manual' end
    end

I guess the rule could be that only redefinitions in the same
class/module transfer the property of being a property accessor.

Another option might be to use attr_reader/attr_accessor. If no
parameters are passed the next method becomes a property accessor. In
MRI passing no parameters is possible and has no effect.

    class Test
      attr_reader
      def m; @m end

      attr_writer   # this is not really needed as any method whose 

name ends = could automatically be considered a property/indexer setter
def m=(val) @m = val end

      def initialize; @a, @m = 'automatic', 'manual' end
    end

Tomas

Jorg,

It is a good idea, but I have tried this already, and it still fails.
By
re-defining the method after attr_accessor, you blow away whatever magic
happens that causes it to be a property at interop time.

Unless… you are suggesting that this is how it SHOULD work.

I think either approach makes sense. A special interop class method is
nice
because it is explicit. Having method redefinition do the job is nice
because it doesn’t require a special class method :slight_smile:

What does everyone else think?

If I get the time, I was planning on getting my hands in the code and
trying
to implement it.

Thanks,
Brian

2010/7/23 Jörg W Mittag
<[email protected][email protected]

Brian G. wrote:

It is a good idea, but I have tried this already, and it still fails.

So did I :slight_smile:

By
re-defining the method after attr_accessor, you blow away whatever magic
happens that causes it to be a property at interop time.

Unless… you are suggesting that this is how it SHOULD work.

Yes, that’s what I meant.

I think either approach makes sense. A special interop class method is nice
because it is explicit. Having method redefinition do the job is nice
because it doesn’t require a special class method :slight_smile:

What does everyone else think?

Actually, I believe both make sense. Having method redefinition not
work simply violates at least my Principle of Least Astonishment, so
it needs to be fixed anyway. But it alone is not enough: sometimes you
might want to have different names for your .NET property and your
Ruby methods. A good example might be a readonly boolean property:

prop_getter :isValid => :valid?
def valid?
  @is_valid
end

Actually, now that I think about it, what about just overloading
attr_accessor and friends? In plain Ruby,

attr_reader :isValid => :valid?

is illegal anyway. Together with working method redefinition, I
believe this would cover all use cases, no?

[Note: the risk is that at some time in the future, Ruby might allow
this notation to have the getter/setter names decoupled from the
instance variable names. Actually, now that I think about it, I might
suggest that right now :slight_smile: It always bugged me that you cannot simply
define boolean accessors because that would try to create a @valid?
instance variable, which is illegal.]

jwm

Unless CRuby implements properties I don’t like introducing property
“names” that are different from foo, foo= pattern. For now that’s just
not the Ruby way.

Tomas

I agree, I don’t like the idea of doing something that conflicts with
current Ruby standards.

I do like the prop_getter idea though, but that is essentially what we
are talking about with an interop class method. I also have written
class methods to do the Boolean idea before. Look through my CP_Bugger
source to see some examples.

JD

So, I was looking at a unit test in the IR source code:

IronRuby.Tests/Runtime/HostingTests.cs:CustomTypeDescriptor1()

It is interesting, because it implies that the getter/setter should be
implicit based on foo and foo= being defined. The property is
retrievable
and even settable via the ICustomTypeDescriptor.GetProperties().

It appears to me that this implicit property should also be be available
via
the dynamic invocation without the need to declare it via prop_accessor.

Am I off base?
Brian