From: dblack@... Date: 2006-07-10T09:06:58+09:00 Subject: Re: why does block know about one instance variable and not the other? Hi -- On Mon, 10 Jul 2006, anne001 wrote: > Thank you for your response. > > It did occured to me sometime after I wrote the post that the > difference between the two instance variables was that one was outside > the define and the other inside. A look at > http://www.ruby-doc.org/docs/UsersGuide/rg/instancevars.html > and other examples, shows that the instance variable is always defined > in a method without saying why. > > So I was very glad to find your response. > > I thought of an instance as a copy of the class. so implicitely I > assumed it would get a copy of an instance variable. Maybe I should > think of an object as an inheritance of methods: So it inherits > methods, not variables. "Inheritance" is a bit of a misnomer. A class (or module) contains methods. Every object has a method look-up path, which traverses multiple classes and modules. When you call a method, the object searches for a matching method in the relevant classes and modules, in a prescribed order. That sounds like a wordy way to put it -- but when you start getting into things like including modules in singleton classes, and what not, the look-up path view is the one that will keep it straight for you. > But if that was the rule, it would not work for constants either > http://www.ruby-doc.org/docs/UsersGuide/rg/constants.html > in the example there, it would get a method and have no idea what the > constants were. Constants have different scope, and they always belong to a class or module. > your example helped clarify what is going on. > > class C > puts self > @var = 1 > puts self > def x > puts self > @var = 2 > end > end > p "create new instance of C" > y= C.new > p y > p "run method which creates an instance variable" > y.x > p y > > class D > puts self > @@var = 1 > puts self > def x > puts self > @@var = 2 > end > end > p "create new instance of D" > y= D.new > p y > p "run method which creates an instance variable" Actually you're using class variables here (@@var). They're very different from instance variables. > y.x > p y > > In class C, running x adds @var to the object, but in D, running x does > not add @@var. > > @var is an instance variable that belongs to whatever object is > "self" at that moment in runtime. > > QUESTION: If that is the case, why does puts self not append @var=1 to > object C the way it > appends @var=2 to the instance? > # That's just the convention of the string representation of classes vs. non-classes. > In any case, the code in C outside of the methods is only run once when > the new method is called, and the object is C. OK. I had not thought of > it that way. Actually the code in C outside of the methods is run when the interpreter first encounters it. Even if you never called C.new, the code in the definition block of C would be executed. > So is this an ok way to think about objects: > 1. Objects inherit methods See above. > 2. The variable environment includes, read access to Class constants, > r/w to @@var and r/w to global variables @@var (class variables) have some strange scoping rules, but basically inside an instance method and outside the method, in the class body, the @@var you see is the same @@var (unlike instance variables). > 2. @var become local to whatever object is self at the moment they are > created. And whenever you see @var, it's the @var belonging to self. David -- http://www.rubypowerandlight.com => Ruby/Rails training & consultancy http://www.manning.com/black => RUBY FOR RAILS, the Ruby book for Rails developers http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log dblack@wobblini.net => me