Unexpected scope range

I am new to Ruby but have a strong java background.

So far I have been enjoying Ruby a great deal.

But I have been wondering about why the scope of variables works as it
does. It seems that very often, I need to prefix my variables with
either @ or $ in order to access them in method calls.
I did some searching for an explanation but did not find any.

In java variables can be defined and used like this:

Object x = myX;

public void printx(){
System.out.println(x);
}

x is available when the method is called. This is not the case with
Ruby:

x = myX

def printx
puts x
end

Running the code will produce an error: “NameError: undefined local
variable or method `x’ for main:Object”.

In order to reveal x to the method one must, for instance, declare it
global by prefixing the $. This requires more typing (which, in many
other respects, ruby tries to avoid).

How come the scope works in this way? I expected the visibility of
variables to flow down into the code tree (but not up, of course).

Thank you.

Regards, Andreas

Andreas W. wrote:

How come the scope works in this way? I expected the visibility of
variables to flow down into the code tree (but not up, of course).

In Ruby, variables used within a method are marked this way:

example # method local
@example # class instance variable
@@example # class variable
$example # global variable

The term “class variable” above refers to a variable that is common to
the
entire class, and “instance variable” refers to a variable that is
unique
to an instance of the class.

This means you can use @this_syntax to refer to a variable you want to
share
between method within a class, without using global variables, something
one wants to avoid unless necessary.

On Dec 5, 2006, at 11:45 AM, Paul L. wrote:

In Ruby, variables used within a method are marked this way:
[…]
@example # class instance variable

This doesn’t seem like standard terminology to me. Usually these
are simply called ‘instance variables’ as each instance of a class
(or each object if you prefer) has its own private set of instance
variables. These variables belong to the instance (object) and not
to the associated class.

Gary W.

unknown wrote:

Hi –

On Wed, 6 Dec 2006, Andreas W. wrote:

How come the scope works in this way? I expected the visibility of
variables to flow down into the code tree (but not up, of course).

def starts a new local scope, so local variables defined outside it
won’t be visible. I can’t answer the question defensively – that is,
I can’t say why it is in relation to Java, since I have no reason to
think it was designed in relation to Java :slight_smile:

Instance variables (@this) are always associated with, and owned by,
whatever object is in the role of “self”, the default object. Inside
a method definition, self is (or is going to be, when the method
eventually gets called) the object running the method.

Global variables ($this) are just global variables, and have the usual
properties of such variables: they walk through walls, so to speak,
when it comes to scope, and generally discourage nice encapsulation of
code and interaction of objects.

David

Thanks for your replies.

It would seems this is just something I have “gotten used to” with java.
Looking over some of the things I did in the past (in learning ruby) it
is clear that constants (variables with capital starting letter), which
do flow past def statements could have removed a great part of my $'s.
To illustrate the difference between local and constant variables:

x=1
def print_local
puts x
end

(fails)

X=1
def print_constant
puts X
end

(prints value of capital X)

Best regards
Andreas

Hi –

On Wed, 6 Dec 2006, Andreas W. wrote:

How come the scope works in this way? I expected the visibility of
variables to flow down into the code tree (but not up, of course).

def starts a new local scope, so local variables defined outside it
won’t be visible. I can’t answer the question defensively – that is,
I can’t say why it is in relation to Java, since I have no reason to
think it was designed in relation to Java :slight_smile:

Instance variables (@this) are always associated with, and owned by,
whatever object is in the role of “self”, the default object. Inside
a method definition, self is (or is going to be, when the method
eventually gets called) the object running the method.

Global variables ($this) are just global variables, and have the usual
properties of such variables: they walk through walls, so to speak,
when it comes to scope, and generally discourage nice encapsulation of
code and interaction of objects.

David

Le mardi 05 décembre 2006 17:45, Paul L. a écrit :

In java variables can be defined and used like this:
x = myX
other respects, ruby tries to avoid).

The term “class variable” above refers to a variable that is common to the
entire class, and “instance variable” refers to a variable that is unique
to an instance of the class.

This means you can use @this_syntax to refer to a variable you want to
share between method within a class, without using global variables,
something one wants to avoid unless necessary.

As a Java programmer, you are used to declare any attribute (ie 

instance
variables) in the “body” of the class, outside any method. This is not
how it
works in Ruby, because no declaration is needed. So, as Paul wrote, you
can
use directly @example within your methods with nothing more elsewhere.
If you are a bit confused of not having a place, in a class, where to
put all
your instance variables, put it in the initialize method.

Note that int this class :

class A
@var
def meth
@var
end
end

the two @var are not the same !

About global variables, I personnaly never used them. It's useful for 

things
like $stdin or $DEBUG, but nothing more.

On Dec 5, 2006, at 13:35 , Paul L. wrote:

to the associated class.

Yes, this is only a matter of terminology. My term “class instance”
is the
same as your use of “instance”. I say it this way only for clarity of
expression.

There is no such thing as a “class instance variable” in Ruby.
Classes are real objects too, and they have “instance variables” just
like everybody else.


Eric H. - [email protected] - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!

[email protected] wrote:

to the associated class.
Yes, this is only a matter of terminology. My term “class instance” is
the
same as your use of “instance”. I say it this way only for clarity of
expression.

Hi –

On Wed, 6 Dec 2006, [email protected] wrote:

to the associated class.
Sometimes people say “class instance variable” to mean “instance
variable of a class object”, if for some reason it seems like just
saying “instance variable” might sound like it means “instance
variable in an instance method” (and I think that ambiguity can arise,
in some conversational contexts). But “class instance variable” never
means or implies or connotes “instance variable” in general, and at
the language level there’s no separate “class instance variable”
construct or entity.

David

Eric H. wrote:

/ …

There is no such thing as a “class instance variable” in Ruby.

Assertion 1.

Classes are real objects too, and they have “instance variables” just
like everybody else.

Assertion 2 appears to contradict assertion 1.

Strictly speaking, this is about classes, only peripherally about Ruby,
and
Ruby shouldn’t deviate from the general terminology used to describe
classes and their aspects.

If you want assert that there is such a thing as a class instance
variable
that is global to all members of the class … hey, go for it. I find it
confusing, reasonable people will differ.

IMHO, classes have instances, but classes are not themselves
instances.
Objects created using class constructors are instances of that class.

I don’t normally do this (it comes off as an empty appeal to authority),
but
please look at page 388 of the Pickaxe book, under the heading “class
instance variables”. The discussion is about what you have been calling
instance variables, and I have been calling … class instance
variables.

On Wed, 6 Dec 2006, Paul L. wrote:

IMHO, classes have instances, but classes are not themselves instances.

No, that’s wrong. Classes are unambiguously and unequivocally
instances of the class Class.

The “classes are objects too” principle is very, very important in
Ruby. Lots of things happen that are impossible to understand without
understanding that principle.

As for instance variables: each and every instance variable belongs to
a particular object, and every object is an instance of some class.

class C
@x = 1 # an instance variable of the object C, which is
# an instance of Class
def meth
@x = 1 # an instance variable of any instance of C that
end # calls this method

end

The ownership of instance variables is governed by what object is
playing the role of “self” at the point when the instance variable is
encountered. The object may, indifferently, be an instance of Class,
an instance of String, an instance of MyClass, and so on.

The term “class instance variable” is completely inappropriate, and
potentially very confusing, as a synonym for “instance variable”.

David

On Wed, 6 Dec 2006, Paul L. wrote:

I don’t normally do this (it comes off as an empty appeal to authority), but
please look at page 388 of the Pickaxe book, under the heading “class
instance variables”. The discussion is about what you have been calling
instance variables, and I have been calling … class instance variables.

No; the discussion is about instance variable that belong to class
objects (i.e., instances of Class). Dave makes the distinction
between “class instance variables” and “regular instance variables”
for the sake of pointing up, ultimately, the fact that classes, as
instances, can have instance variables.

At no point does Dave suggest or imply that “class instance variable”
is an appropriate universal term for @this kind of variable.

David

[email protected] wrote:

On Wed, 6 Dec 2006, Paul L. wrote:

IMHO, classes have instances, but classes are not themselves instances.

No, that’s wrong. Classes are unambiguously and unequivocally
instances of the class Class.

Yes, no dispute about that. I ought to have said that class definitions
are
not instances of themselves, which is what I was thinking.

And I am entirely responsible for the confusion I managed to cause.

On Dec 5, 2006, at 18:40 , Paul L. wrote:

Assertion 2 appears to contradict assertion 1.

Strictly speaking, this is about classes, only peripherally about
Ruby, and
Ruby shouldn’t deviate from the general terminology used to describe
classes and their aspects.

I’m sorry if you’ve spent your time trapped in crappy OO languages
like Java and C++ where classes aren’t real objects.

If you want assert that there is such a thing as a class instance
variable
that is global to all members of the class … hey, go for it. I
find it
confusing, reasonable people will differ.

IMHO, classes have instances, but classes are not themselves
instances.

ruby disagrees with your opinion:

ruby -e ‘p Object.class; p Object.ancestors’
Class
[Object, Kernel]

As does “ri Class”.

Objects created using class constructors are instances of that class.

I don’t normally do this (it comes off as an empty appeal to
authority), but
please look at page 388 of the Pickaxe book, under the heading “class
instance variables”. The discussion is about what you have been
calling
instance variables, and I have been calling … class instance
variables.

What the pickaxe refers to as “class instance variables” are
“instance variables of a Class”. There is no difference in instance
variables no matter which object they live in. Clinging futilely to
some believe that there is some difference will only limit your
understanding of Ruby.


Eric H. - [email protected] - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!