# Why does block know about one instance variable and not the

**URL:** <https://www.ruby-forum.com/t/why-does-block-know-about-one-instance-variable-and-not-the/97680>\
**Category:** Ruby\
**Created:** [July 9, 2006, 4:28pm UTC](https://www.ruby-forum.com/t/why-does-block-know-about-one-instance-variable-and-not-the/97680 "2006-07-09T16:28:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![anne001](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/34f0e0/32.png) [@anne001](https://www.ruby-forum.com/u/anne001)\
**Post date:** [July 9, 2006, 4:28pm UTC](https://www.ruby-forum.com/t/why-does-block-know-about-one-instance-variable-and-not-the/97680/1 "2006-07-09T16:28:09Z")

</div>

I can’t find what the problem is with @foundinfo: since it is defined  
outside a block, the block should find it no? @item is defined outside  
the second block and that second block finds it. What is @item and  
@foundinfo different?

Do I have a typo I don’t see, or it there a principle of the thing?

Here is my simplified code with debugging puts

class Linear  
@foundinfo=Hash.new  
p " 1. debugging @foundinfo created"  
p @foundinfo.class#this is ok

def run

```
data="hello dud"
data.split(/</).each do |line|
   line =~ /d(.)d/
    @item=$1
    p "2. debugging, @foundinfo found?"
    p @foundinfo.class # this is not ok, @foundinfo not found

    lines="and so on and some more"
    lines.split(/</).each do |chunk|
           p "3. debugging, @item found?"
           p @item #this is ok, @item found
           p "3. debugging, @foundinfo found?"
           p @foundinfo.class # this is still not ok, @foundinfo

```

not found  
end # end do chunk  
end # end do line  
end # end run

end # end class

a=Linear.new  
a.run

---

<div class="post-metadata">

**Author:** ![anne001](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/34f0e0/32.png) [@anne001](https://www.ruby-forum.com/u/anne001)\
**Post date:** [July 9, 2006, 4:48pm UTC](https://www.ruby-forum.com/t/why-does-block-know-about-one-instance-variable-and-not-the/97680/2 "2006-07-09T16:48:03Z")

</div>

Hi,

On 7/9/06, anne001 [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> class Linear

@foundinfo=Hash.new

> p " 1. debugging @foundinfo created"  
> p @foundinfo.class#this is ok

You should wrap the above section in the initialize method, like so.

def initialize  
@foundinfo = Hash.new  
p " 1. debugging @foundinfo created"  
p @foundinfo.class#this is ok  
end

def run

> ```
> p "3. debugging, @item found?"
> 
> ```
> 
> a=Linear.new  
> a.run

Michael G.

---

<div class="post-metadata">

**Author:** ![anne001](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/34f0e0/32.png) [@anne001](https://www.ruby-forum.com/u/anne001)\
**Post date:** [July 9, 2006, 4:57pm UTC](https://www.ruby-forum.com/t/why-does-block-know-about-one-instance-variable-and-not-the/97680/3 "2006-07-09T16:57:58Z")

</div>

Hi –

On Sun, 9 Jul 2006, anne001 wrote:

> I can’t find what the problem is with @foundinfo: since it is defined  
> outside a block, the block should find it no? @item is defined outside  
> the second block and that second block finds it. What is @item and  
> @foundinfo different?
> 
> Do I have a typo I don’t see, or it there a principle of the thing?

There’s a principle:

Whenever you see this:

```
@var

```

you are seeing an instance variable that belongs to whatever object is  
“self” at that moment in runtime.

Now, watch this:

class C  
puts self  
def x  
puts self  
end  
end

C.new.x

What you get from this code is:

C  
#\<C:0x325648\>

In other words, in the top level of a class definition block, “self”  
is the class object itself (C, in this case). Inside a method  
definition – that is, when that method is eventually executed –  
“self” is the instance that’s executing the method: hence the  
“instance of C” inspect string on the second line.

It follow that when you do this:

class C  
@var = 1  
def x  
@var = 2  
end  
end

you’re dealing with two separate, unrelated instance variables, owned  
by different objects.

David

---

<div class="post-metadata">

**Author:** ![anne001](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/34f0e0/32.png) [@anne001](https://www.ruby-forum.com/u/anne001)\
**Post date:** [July 10, 2006, 1:46am UTC](https://www.ruby-forum.com/t/why-does-block-know-about-one-instance-variable-and-not-the/97680/4 "2006-07-10T01:46:24Z")

</div>

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](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.

But if that was the rule, it would not work for constants either  
[http://www.ruby-doc.org/docs/UsersGuide/rg/constants.html](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.

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”  
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?  
#\<C:0x25b58 @var=2\>

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.

So is this an ok way to think about objects:

1. Objects inherit methods
2. The variable environment includes, read access to Class constants,  
r/w to @@var and r/w to global variables
3. @var become local to whatever object is self at the moment they are  
created.

---

<div class="post-metadata">

**Author:** ![anne001](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/34f0e0/32.png) [@anne001](https://www.ruby-forum.com/u/anne001)\
**Post date:** [July 10, 2006, 2:08am UTC](https://www.ruby-forum.com/t/why-does-block-know-about-one-instance-variable-and-not-the/97680/5 "2006-07-10T02:08:00Z")

</div>

Hi –

On Mon, 10 Jul 2006, anne001 wrote:

> 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](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.

> end  
> 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.

> object C the way it  
> appends @var=2 to the instance?  
> #\<C:0x25b58 @var=2\>

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.

> 1. 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).

> 1. @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

---

<div class="post-metadata">

**Author:** ![anne001](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/34f0e0/32.png) [@anne001](https://www.ruby-forum.com/u/anne001)\
**Post date:** [July 10, 2006, 2:56am UTC](https://www.ruby-forum.com/t/why-does-block-know-about-one-instance-variable-and-not-the/97680/6 "2006-07-10T02:56:57Z")

</div>

anne001 wrote:

> 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.

Instance of a class is not a copy of it. Classes are somewhat templates  
for instances, they define what methods and variables their instances  
will have. But since a Class in Ruby is also an object it can have  
instance variable as well!.

> In class C, running x adds @var to the object,

As it should do

but in D, running x does

> not add @@var.  
> @@var is a special variable that is shared between class and it’s  
> instances (so there is only one @@var, no matter how many instances  
> there are).

> @var is an instance variable that belongs to whatever object is  
> “self” at that moment in runtime.

No, self is different in class context and instance context.

> 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?  
> #\<C:0x25b58 @var=2\>

Class objects have different default implementation of inspect method,  
so they are printed differently using p. There is a way to query object  
about their variables:

p C.instance\_variable\_get("@var")  
-\> 1  
p y.instance\_variable\_get("@var")  
-\> 2

> 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.
> 
> So is this an ok way to think about objects:
> 
> 1. Objects inherit methods

Nope, classes define methods which in turn will be available to their  
instances upon construction

> 1. The variable environment includes, read access to Class constants,  
> r/w to @@var and r/w to global variables  
> Again, depends on the context (receiver aka self)

> 1. @var become local to whatever object is self at the moment they are  
> created.

I’ve never considered instance variables to be local to their instances

- but in a way, yes.

lopex
