Why does block know about one instance variable and not the

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

Hi,

On 7/9/06, anne001 [email protected] 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.

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

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.

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.

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.

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

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