Unexpected scope range

Discussion in 'Ruby' started by Andreas Warberg, Dec 5, 2006.

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

    --
    Posted via http://www.ruby-forum.com/.
     
    Andreas Warberg, Dec 5, 2006
    #1
    1. Advertising

  2. Andreas Warberg

    Guest

    On Dec 5, 2006, at 11:45 AM, Paul Lutus 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 Wright
     
    , Dec 5, 2006
    #2
    1. Advertising

  3. Andreas Warberg

    Guest

    Hi --

    On Wed, 6 Dec 2006, Andreas Warberg wrote:

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


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

    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

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Dec 5, 2006
    #3
  4. unknown wrote:
    > Hi --
    >
    > On Wed, 6 Dec 2006, Andreas Warberg 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 :)
    >
    > 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

    --
    Posted via http://www.ruby-forum.com/.
     
    Andreas Warberg, Dec 5, 2006
    #4
  5. Andreas Warberg

    Olivier Guest

    Le mardi 05 d=E9cembre 2006 17:45, Paul Lutus a =E9crit=A0:
    > Andreas Warberg wrote:
    > > 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 =3D myX;
    > >
    > > public void printx(){
    > > System.out.println(x);
    > > }
    > >
    > > x is available when the method is called. This is not the case with
    > > Ruby:
    > >
    > > x =3D 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).

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


    As a Java programmer, you are used to declare any attribute (ie instance=20
    variables) in the "body" of the class, outside any method. This is not how =
    it=20
    works in Ruby, because no declaration is needed. So, as Paul wrote, you can=
    =20
    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=20
    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 thin=
    gs=20
    like $stdin or $DEBUG, but nothing more.

    =2D-
    Olivier
     
    Olivier, Dec 5, 2006
    #5
  6. Andreas Warberg

    Eric Hodel Guest

    On Dec 5, 2006, at 13:35 , Paul Lutus wrote:
    > wrote:
    >> On Dec 5, 2006, at 11:45 AM, Paul Lutus 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.

    >
    > 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 Hodel - - http://blog.segment7.net

    I LIT YOUR GEM ON FIRE!
     
    Eric Hodel, Dec 6, 2006
    #6
  7. Andreas Warberg

    Guest

    Hi --

    On Wed, 6 Dec 2006, wrote:

    >
    > On Dec 5, 2006, at 11:45 AM, Paul Lutus 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.


    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

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Dec 6, 2006
    #7
  8. Andreas Warberg

    Guest

    On Wed, 6 Dec 2006, Paul Lutus 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

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Dec 6, 2006
    #8
  9. Andreas Warberg

    Guest

    On Wed, 6 Dec 2006, Paul Lutus 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

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Dec 6, 2006
    #9
  10. Andreas Warberg

    Eric Hodel Guest

    On Dec 5, 2006, at 18:40 , Paul Lutus wrote:

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


    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 Hodel - - http://blog.segment7.net

    I LIT YOUR GEM ON FIRE!
     
    Eric Hodel, Dec 6, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    46
    Views:
    971
    Antoon Pardon
    Jul 25, 2006
  2. Lambda
    Replies:
    2
    Views:
    399
    James Kanze
    Jul 16, 2008
  3. Tomoyuki Kosimizu

    Range does not take an Range object.

    Tomoyuki Kosimizu, Nov 25, 2003, in forum: Ruby
    Replies:
    3
    Views:
    154
    Tomoyuki Kosimizu
    Nov 27, 2003
  4. Joe Percival
    Replies:
    4
    Views:
    109
    George Ogata
    Mar 12, 2006
  5. risingfish

    Unexpected scope question

    risingfish, Feb 6, 2012, in forum: Javascript
    Replies:
    2
    Views:
    564
    Scott Sauyet
    Feb 6, 2012
Loading...

Share This Page