C extension: can rb_ivar_set be used to set class variable?

Discussion in 'Ruby' started by lianliming, Dec 14, 2007.

  1. lianliming

    lianliming Guest

    Hi all,

    This is a question on Ruby C extension.

    I have been hacking some existed ruby c extension, and found following
    code:

    VALUE klass = rb_define_class(name, pClass);
    rb_ivar_set(klass, id_some_var, someValue);

    From the book "Programming Ruby, Second Edition", I know the prototype
    for rb_ivar_set is like:

    VALUE rb_ivar_set( VALUE obj, ID name, VALUE value )

    And it says the first parameter should be an obj, while as we can see
    from above, the code I am hacking is passing "klass" returned by
    rb_define_class to rb_ivar_set.

    So I wonder if this is a way to set class variable for a class. I am
    really confused because the document says it should be used to set
    value of instance variable to a given obj. Am I missing some
    knowledge?

    Any help is appreciated and thanks in advance!
    lianliming, Dec 14, 2007
    #1
    1. Advertising

  2. Hi,

    At Fri, 14 Dec 2007 14:20:01 +0900,
    lianliming wrote in [ruby-talk:283492]:
    > So I wonder if this is a way to set class variable for a class. I am
    > really confused because the document says it should be used to set
    > value of instance variable to a given obj. Am I missing some
    > knowledge?


    No, use rb_cvar_set to set class variables. rb_ivar_set sets
    an instance variable of a class instance. I.E.,

    class Foo
    @foo = "ivar"
    @@foo = "cvar"
    end

    --
    Nobu Nakada
    Nobuyoshi Nakada, Dec 14, 2007
    #2
    1. Advertising

  3. lianliming

    lianliming Guest

    Thanks for your reply!

    > No, use rb_cvar_set to set class variables. rb_ivar_set sets
    > an instance variable of a class instance. I.E.,
    >
    > class Foo
    > @foo = "ivar"
    > @@foo = "cvar"
    > end


    Will the instance variable "@foo"'s value declared as the above
    example can be referenced in an object of Class Foo?

    Please look at following example:

    class Foo
    @foo = "ivar"

    def printFoo
    puts @foo
    end
    end

    f=Foo.new
    f.printFoo
    ========> nil

    So now, I am curious to know, why the function rb_ivar_set allows
    passing a "klass" as the first parameter to set value of a instance
    variable which can't be referenced by its objects.
    lianliming, Dec 14, 2007
    #3
  4. instance variable of class instance (Re: C extension: can rb_ivar_set be used to set class variable?)

    Hi,

    At Fri, 14 Dec 2007 15:15:02 +0900,
    lianliming wrote in [ruby-talk:283498]:
    > Will the instance variable "@foo"'s value declared as the above
    > example can be referenced in an object of Class Foo?


    No, two different objects's instance variables.

    Now your question is not related to C extension. I guess
    others could explain it much better than me.

    --
    Nobu Nakada
    Nobuyoshi Nakada, Dec 14, 2007
    #4
  5. On 12/14/07, lianliming <> wrote:
    > Thanks for your reply!
    >
    > > No, use rb_cvar_set to set class variables. rb_ivar_set sets
    > > an instance variable of a class instance. I.E.,
    > >
    > > class Foo
    > > @foo = "ivar"
    > > @@foo = "cvar"
    > > end

    >
    > Will the instance variable "@foo"'s value declared as the above
    > example can be referenced in an object of Class Foo?
    >
    > Please look at following example:
    >
    > class Foo
    > @foo = "ivar"
    >
    > def printFoo
    > puts @foo
    > end
    > end
    >
    > f=Foo.new
    > f.printFoo
    > ========> nil
    >
    > So now, I am curious to know, why the function rb_ivar_set allows
    > passing a "klass" as the first parameter to set value of a instance
    > variable which can't be referenced by its objects.


    rb_ivar_set takes an object as the first parameter. Classes are
    objects, and as such can have their own instance variables which are
    visible in class methods. These are called class instance variables,
    and are quite different from class variables. Being instance
    variables, class instance variables are only visible to methods of the
    object to which they are attached, which in the case of class instance
    variables would be class methods.

    There's also a subtlety to the Ruby object model which can be
    surprising to folks familiar with other OO languages. In many
    languages including Java, C++ and Smalltalk, one of the functions of a
    class is to serve as a template which maps the layout of the object in
    memory, in a manner analogous to a C struct, so that method code can
    reference instance variables by offset from the address of the
    instance. Ruby classes don't really "know" about the instance
    variables of their instances, since instance variables( actually all
    variables) aren't declared in Ruby. Instance variables get attached
    to an instance dynamically when a method is executed which mentions
    that instance variable. In fact different instances of the same class
    can have different sets of instance variables, and the set of instance
    variables of a particular object can change over time.

    Conceptually, and actually at least for Matz's Ruby Implementation,
    instance variables are resolved by accessing a per-instance internal
    hash table which maps the instance variable name (including the @
    sigil) as a symbol to the value.

    Class variables, marked with the @@ sigil are also looked up in a hash
    associated with the class object. The difference is that for class
    variables, if the key is not found in the hash, the search considers
    iteratively up the superclass chain, and for class methods, it's the
    class and not the metaclass chain which is traversed. This means that
    class variables are visible to both instance and class methods of the
    class where they live and that classes subclasses. The MRI, at least
    the last time I looked, actually puts class variables in the same hash
    as class instance variables, i.e. the class objects instance variable
    hash. It's the difference in the sigils which affects how they are
    seen and used.

    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
    Rick DeNatale, Dec 14, 2007
    #5
  6. lianliming

    Heath Novak Guest

    unsubscribe
    On Dec 13, 2007, at 10:27 PM, Nobuyoshi Nakada wrote:

    > Hi,
    >
    > At Fri, 14 Dec 2007 14:20:01 +0900,
    > lianliming wrote in [ruby-talk:283492]:
    >> So I wonder if this is a way to set class variable for a class. I am
    >> really confused because the document says it should be used to set
    >> value of instance variable to a given obj. Am I missing some
    >> knowledge?

    >
    > No, use rb_cvar_set to set class variables. rb_ivar_set sets
    > an instance variable of a class instance. I.E.,
    >
    > class Foo
    > @foo = "ivar"
    > @@foo = "cvar"
    > end
    >
    > --
    > Nobu Nakada
    >
    Heath Novak, Dec 14, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,684
    Thomas Weidenfeller
    Oct 12, 2005
  2. Andrew Degtiariov
    Replies:
    2
    Views:
    456
    Andrew Degtiariov
    Sep 17, 2004
  3. Casey Hawthorne
    Replies:
    1
    Views:
    688
    Arne Vajhøj
    Mar 18, 2009
  4. Vskz
    Replies:
    0
    Views:
    329
  5. Ted Byers
    Replies:
    23
    Views:
    399
    Peter J. Holzer
    Nov 15, 2008
Loading...

Share This Page