From: Rick DeNatale Date: 2009-05-27T22:32:16+09:00 Subject: Re: How do Class definitions in Ruby differ from other OO languages? On Wed, May 27, 2009 at 3:01 AM, Charles Oliver Nutter wrote: > kunjaan wrote: >> >> What do you mean when you say"Class definitions are executable code". >> How do classes differ from other OO languages? > > I like to say it like this: > > Ruby doesn't have class declarations. "Declaring" a class is actually just > constructing a new Class object and running code against it. All classes > start out blank and must have methods and instance variables added to them > at runtime. As I tried to point out earlier in this thread, that last phrase is a bit ambiguous. If we're talking about "class instance variables" then yes, Ruby classes have instance variables added to them at runtime, but classes don't "know" about the set of instance variables that their INSTANCEs have, in the same way that the do in Java or Smalltalk. Each instance acquires instance variables only when a method is run with that instance as self which defines the iv by initializing it. At least this is what it must look like to the Ruby program, defined? @iv must return nil for each instance until @iv has been defined in THAT instance: class Foo attr_accessor :iv def iv_defined? defined? @iv end end f1 = Foo.new f2 = Foo.new f1.iv_defined? # => nil f2.iv_defined? # => nil f1.iv = 1 f1.iv_defined? # => "instance-variable" f2.iv_defined? # => nil Implementations might play some tricks due to the underlying VM implementation like pre-allocating slots to hold some ivs, but that has to be hidden from the Ruby programmer. If used it needs to be one of those VM implementation 'cheats' which the VM implementer needs to avoid being caught using. MagLev does, or maybe did, do something like this. It assigns the first few ivs it sees to fixed slots, since the Smallalk object model prefers fixed iv name to slot offset mappings. They had some issues with not handling defined? properly something which the RubySpec didn't cover until I added that http://rubyspec.org/issues/show/82 I'm not sure exactly what changes that caused in their implementation. I don't know what JRuby does. Ruby 1.8, uses a hash to implement ivs, Ruby 1.9 uses a dynamic allocation technique which DOEs move the hash to the instance's immediate class, and maps iv names to slot indexes, in an array of slots either directly inside the object's 'box' for an instance with a very small number of IVs or to a separate array, with slots initialized to a value which represents not nil, but undefined. One of the things that's different in this implemenation is that in a case like class A attr_accessor :a, :b end class B < A end the offset of @a might be different for instances of A than for instances of B, i.e. the offsets are NOT inherited. -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale