[Ironruby-core] Setting and initializing instance variables on RubyClasses

Tomas Matousek Tomas.Matousek at microsoft.com
Wed Jul 7 12:15:49 EDT 2010


By native Ruby library/extension I meant an implementation in C.

Although possible it's not easy to simulate Ruby classes definition in C# in a declarative way. I would suggest writing your implementation in Ruby and calling .NET when you need so using IronRuby's .NET interop.
If you absolutely need to implement your Ruby classes in C# (I would be interested to understand why) you can use C# instance fields instead of Ruby's instance variables. They won't be exposed as instance variables to Ruby but they would be faster to work with. The fact they are not exposed shouldn't matter since instance variables should be a private implementation detail of the class anyways. 

It is more complicated with per-class data. You shouldn't use static fields since the value should be bound to Ruby runtime. To allocate data bound to a runtime we provide GetOrCreateLibraryData method on RubyContext. You'll find a few places where it's used in IronRuby.Library. But before you dig into that consider writing your code in Ruby and perhaps parts of it that are perf critical in pure C# (w/o Ruby specific attributes). Our C# interop is strong so there shouldn't be generally a need for writing Ruby code in C#.

Tomas

-----Original Message-----
From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Charles Strahan
Sent: Monday, July 05, 2010 11:55 PM
To: ironruby-core at rubyforge.org
Subject: Re: [Ironruby-core] Setting and initializing instance variables on RubyClasses

Wow, that was quick!  Thanks Tomas.


If by Ruby native you mean mostly implemented in Ruby, then no.

I mentioned the Ruby snippets just for clarification.  If I understand correctly, SetClassVariable has the same semantics as declaring what Ruby would call a class variable, as in @@some_var.  @@some_var would be visible to the whole class hierarchy, so `FancyGraphics < Graphics; end` would share the same @@some_var instance - which is _not_ what I'd like.

Just curious how that might work using the IR APIs.


I assume the second question made sense. If not, let me know.


Cheers,

Charles

-----Original Message-----
From: ironruby-core-bounces at rubyforge.org
[mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Tomas Matousek
Sent: Tuesday, July 06, 2010 1:17 AM
To: ironruby-core at rubyforge.org
Subject: Re: [Ironruby-core] Setting and initializing instance variables on RubyClasses

What is your overall goal? Are you implementing a Ruby native library? 

Tomas

-----Original Message-----
From: ironruby-core-bounces at rubyforge.org
[mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Charles Strahan
Sent: Monday, July 05, 2010 10:59 PM
To: ironruby-core at rubyforge.org
Subject: [Ironruby-core] Setting and initializing instance variables on RubyClasses

Hello,

How can I go about setting an instance variable on a RubyClass?

Here's some code for context:

    [RubyClass("Graphics")]
    public class Graphics
    {
        [RubyMethod("frame_rate", RubyMethodAttributes.PublicSingleton)]
        public static int GetFrameRate(RubyClass self)
        {
            // What goes here?
            // I could use self.TryGetClassVariable, but that's a *class* variable, correct?
            // I want to achieve the same thing as "return @frame_rate",
            // not "return @@frame_rate"
        }

        [RubyMethod("frame_rate=", RubyMethodAttributes.PublicSingleton)]
        public static void SetFrameRate(RubyClass self, int frameRate)
        {
            // Same thing here. I could do this:
            // self.SetClassVariable("frame_rate", frameRate);
            // but I want to achieve the same as this:
            // @frame_rate = frame_rate
        }
    }


Another option *just* dawned on me; how about these two:
self.Context.SetInstanceVariable(self, "frame_rate", frameRate); self.Context.TryGetInstanceVariable(self, "frame_rate", out frameRate);

Is that what I'm looking for?


One more question:  is there a way to get the library initializer to invoke a callback so that I may perform some initialization for the RubyClass itself?  In the case above, I'd like to initialize the frame_rate when the RubyClass is created.  As an example:

class Graphics
  attr_accessor :frame_rate
  frame_rate = 40
end
...
Graphics.frame_rate = something_else


I'd like that "frame_rate = 40" to happen when the assembly is loaded by the IronRuby runtime, if possible.  I'm sure I could type that into my auto-generated LibraryInitializer, but I'd rather do this declaratively, perhaps using Attributes (like RubyMethod and RubyClass, etc).


Thanks,
-Charles

_______________________________________________
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

_______________________________________________
Ironruby-core mailing list
Ironruby-core at rubyforge.org
http://rubyforge.org/mailman/listinfo/ironruby-core



More information about the Ironruby-core mailing list