On 12/14/07, lianliming [email protected] wrote:
Will the instance variable “@foo”'s value declared as the above
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.
My blog on Ruby