# C extension: can rb\_ivar\_set be used to set class variable?

**URL:** <https://www.ruby-forum.com/t/c-extension-can-rb-ivar-set-be-used-to-set-class-variable/123118>\
**Category:** Ruby\
**Created:** [December 14, 2007, 6:21am UTC](https://www.ruby-forum.com/t/c-extension-can-rb-ivar-set-be-used-to-set-class-variable/123118 "2007-12-14T06:21:39Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![lianliming](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/b38774/32.png) [@lianliming](https://www.ruby-forum.com/u/lianliming)\
**Post date:** [December 14, 2007, 6:21am UTC](https://www.ruby-forum.com/t/c-extension-can-rb-ivar-set-be-used-to-set-class-variable/123118/1 "2007-12-14T06:21:39Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![lianliming](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/b38774/32.png) [@lianliming](https://www.ruby-forum.com/u/lianliming)\
**Post date:** [December 14, 2007, 6:29am UTC](https://www.ruby-forum.com/t/c-extension-can-rb-ivar-set-be-used-to-set-class-variable/123118/2 "2007-12-14T06:29:15Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![lianliming](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/b38774/32.png) [@lianliming](https://www.ruby-forum.com/u/lianliming)\
**Post date:** [December 14, 2007, 7:16am UTC](https://www.ruby-forum.com/t/c-extension-can-rb-ivar-set-be-used-to-set-class-variable/123118/3 "2007-12-14T07:16:39Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![lianliming](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/b38774/32.png) [@lianliming](https://www.ruby-forum.com/u/lianliming)\
**Post date:** [December 14, 2007, 2:06pm UTC](https://www.ruby-forum.com/t/c-extension-can-rb-ivar-set-be-used-to-set-class-variable/123118/4 "2007-12-14T14:06:59Z")

</div>

On 12/14/07, lianliming [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Will the instance variable “@foo”'s value declared as the above  
> 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/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![lianliming](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/b38774/32.png) [@lianliming](https://www.ruby-forum.com/u/lianliming)\
**Post date:** [December 14, 2007, 7:51am UTC](https://www.ruby-forum.com/t/c-extension-can-rb-ivar-set-be-used-to-set-class-variable/123118/5 "2007-12-14T07:51:43Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![lianliming](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/b38774/32.png) [@lianliming](https://www.ruby-forum.com/u/lianliming)\
**Post date:** [December 14, 2007, 4:38pm UTC](https://www.ruby-forum.com/t/c-extension-can-rb-ivar-set-be-used-to-set-class-variable/123118/6 "2007-12-14T16:38:59Z")

</div>

unsubscribe
