Attempted roadmap of future instance variables

Hi –

I figure that I owe the world at least a shot at clearing the cobwebs
(of my own creation, that is :slight_smile: on this instance variable thing.

So… for those still reading… here’s what I really think is being
proposed:

class A
def m
@var = “hi” # regular instance variable
@_var = “hello” # class-local instance variable
end
end

class B < A
def n
puts @var # same as @var, above
puts @_var # not same as @_var above
end
end

o = B.new
o.m
o.n

=> Output:

hi # the @var that was set in A#m is used here
nil # the @_var that was in A#m is not used here
# (because we’re now in a method defined in B,
# a subclass of A, and class local instance
# variables are not shared by subclasses)

In other words:

  • Regular instance variables live per-name per-object
    (o has exactly one @var).

  • Class-local instance variables live per-name per-object per-class
    (o’s methods defined in A have a @_var, and o’s methods defined in
    B have a different @_var).

David

···


David A. Black
dblack@wobblini.net

David A. Black wrote:

Hi –

I figure that I owe the world at least a shot at clearing the
cobwebs (of my own creation, that is :slight_smile: on this instance
variable thing.

So… for those still reading… here’s what I really think is being
proposed:

I do …

class A
def m
@var = “hi” # regular instance variable
@_var = “hello” # class-local instance variable
end
end

class B < A
def n
puts @var # same as @var, above
puts @_var # not same as @_var above
end
end

o = B.new
o.m
o.n

=> Output:

hi # the @var that was set in A#m is used here
nil # the @_var that was in A#m is not used here
# (because we’re now in a method defined in B,
# a subclass of A, and class local instance
# variables are not shared by subclasses)

In other words:

  • Regular instance variables live per-name per-object
    (o has exactly one @var).

  • Class-local instance variables live per-name per-object per-class
    (o’s methods defined in A have a @_var, and o’s methods defined in
    B have a different @_var).

Thank you very for this comprehensive write up …

/Christoph

So what is the relationship between @_ vars and @vars that are defined in a
class context (if any)? Is this just to allow easier access to class local
vars (that you can already define)? Does below describe the situation
accurately?

class A
@a = 1 # a is a class local variable
@_a = 2 # a is also a class local variable
@@a = 3 # a is a global variable whose visibility is itself and its
sub-classes

def A.a		# define to allow access to class's instance var
	@a
end

def display
	puts "a (class local - current) = #{self.class.a}"
	puts "a (class local - new) = #{@_a}"
	puts "a (class global) = #{@@a}"
end

end

class B < A
end

A.new.display
=> a (class local - current) = 1
=> a (class local - new) = 2
=> a (class global) = 3

B.new.display
=> a (class local - current) =
=> a (class local - new) =
=> a (class global) = 3

Steve Tuckner

···

-----Original Message-----
From: David A. Black [mailto:dblack@wobblini.net]
Sent: Tuesday, December 02, 2003 9:24 AM
To: ruby-talk ML
Subject: Attempted roadmap of future instance variables…

Hi –

I figure that I owe the world at least a shot at clearing the cobwebs
(of my own creation, that is :slight_smile: on this instance variable thing.

So… for those still reading… here’s what I really think is being
proposed:

class A
def m
@var = “hi” # regular instance variable
@_var = “hello” # class-local instance variable
end
end

class B < A
def n
puts @var # same as @var, above
puts @_var # not same as @_var above
end
end

o = B.new
o.m
o.n

=> Output:

hi # the @var that was set in A#m is used here
nil # the @_var that was in A#m is not used here
# (because we’re now in a method defined in B,
# a subclass of A, and class local instance
# variables are not shared by subclasses)

In other words:

  • Regular instance variables live per-name per-object
    (o has exactly one @var).

  • Class-local instance variables live per-name per-object per-class
    (o’s methods defined in A have a @_var, and o’s methods defined in
    B have a different @_var).

David


David A. Black
dblack@wobblini.net

David A. Black wrote:

So… for those still reading… here’s what I really think is being
proposed:

class A
def m
@var = “hi” # regular instance variable
@_var = “hello” # class-local instance variable
end
end

For what it’s worth, I don’t think this is a good syntax. To me, an
underscore is an alphanumeric character. It’s special because it is the
only non-letter, non-number that can appear in the middle of a variable name:

@foo_bar # legal
@foo.bar # not the same thing
@foo@bar # illegal

Making @_ a special case is bound to be confusing, because of this. There
is also the fact that normally variable names with a leading underscore are
a notation that something is internal, and not normally enforced as
something different.

On the other hand, this is consistent with other instances where the first
character of a symbol modifies its behaviour (i.e. if it starts with an
uppercase letter, it is a constant).

Mainly, I suppose, this just brings back ugly memories of languages that
lack truly private variables, so resort to notational hacks like leading
underscores.

Maybe a leading underscore by itself would be less confusing/distasteful?

class A
def m
@var = “hi” # regular instance variable
_var = “hello” # class-local instance variable
end
end

Ben

Steve Tuckner wrote:

So what is the relationship between @_ vars and @vars that
are defined in a class context (if any)? Is this just to
allow easier access to class local vars (that you can already
define)? Does below describe the situation accurately?

class A
@a = 1 # a is a class local variable
@_a = 2 # a is also a class local variable

No these are entirely different beasts - they are “class
instance variables” (I am just ignoring the fact that the
second is a “class local” variant - since this would probable
create further confusion).

/Christoph

Hi –

So what is the relationship between @_ vars and @vars that are defined in a
class context (if any)? Is this just to allow easier access to class local
vars (that you can already define)? Does below describe the situation
accurately?

I think that @_ and @ variables would behave identically when it came
to Class objects’ instance variables – simply because you can’t
subclass Class, so the issue of whether the same or an old or new
variable is in use would never arise. In other words, the situation
exactly analogous to what I did before would be:

class Class
def m
@var = “hi”
@_var = “hello”
end
end

class B < Class # error
def n
puts @var
puts @_var
end
end

which can never happen.

Also, I assume (and hope :slight_smile: that all of this will still be governed
by the “every object can have its own instance variables” principle.
That means that if an object is a Class, and has its own instance
variables, they will not be directly visible to other objects
(including instances of that class).

Therefore, in your example:

class A
@a = 1 # a is a class local variable
@_a = 2 # a is also a class local variable
@@a = 3 # a is a global variable whose visibility is itself and its
sub-classes

def A.a # define to allow access to class’s instance var
@a
end

def display
puts “a (class local - current) = #{self.class.a}”
puts “a (class local - new) = #{@_a}”

@_a here would refer to the @_a of an instance of A, not A’s own @_a.
And an instance of A, say ‘a’ in:

a = A.new

is a different object – a different ‘self’ – from A, and therefore
does not have direct lexical access to A’s own instance variables,
only its own.

That, in turn, means you’ve asked it to display an uninitialized
instance variable, so here:

A.new.display
=> a (class local - current) = 1
=> a (class local - new) = 2

you should get nil, not 2.

David

···

On Wed, 3 Dec 2003, Steve Tuckner wrote:


David A. Black
dblack@wobblini.net

I think that @_ and @ variables would behave identically when it came
to Class objects' instance variables

What do you expect ?

   class A
      @_m = 'A::_m'
      @m = 'A::m'
   
      def self.a
         p @m, @_m
      end
   end
   
   class B < A
      @_m = 'B::_m'
      @m = 'B::m'
   
      def self.a
         p @m, @_m
         super
      end
   end

   B.a

Guy Decoux

Thank David for saving my a… on this one - I apperent
I did not even read Steve’s first couple lines and misinterpret
the rest accordingly - Anyway entirely I agree with your analysis

  • (okay I didn’t read it carefully but it looks fine:-)

/Christoph

···

-----Original Message-----
From: David A. Black [mailto:dblack@wobblini.net]
Sent: Tuesday, 02 December, 2003 05:56 PM
To: ruby-talk ML
Subject: Re: Attempted roadmap of future instance variables…

Hi –

On Wed, 3 Dec 2003, Steve Tuckner wrote:

So what is the relationship between @_ vars and @vars that
are defined
in a class context (if any)? Is this just to allow easier access to
class local vars (that you can already define)? Does below describe
the situation accurately?

I think that @_ and @ variables would behave identically when
it came to Class objects’ instance variables – simply
because you can’t subclass Class, so the issue of whether the
same or an old or new variable is in use would never arise.
In other words, the situation exactly analogous to what I did
before would be:

Maybe I am being dense, so bear with me…

So @_var does not refer to the class instance variable @var? If @_var
defined in a class context is different from @_var in an instance then how
does one refer to the @_var created in the instance context in the class
context?

I would think that @_var in the instance context should be the same as
refering to the @var in the class context. It would be like having
attr_accessor for @var with a little sugar for the instance context.

Steve Tuckner

···

-----Original Message-----
From: David A. Black [mailto:dblack@wobblini.net]
Sent: Tuesday, December 02, 2003 10:56 AM
To: ruby-talk ML
Subject: Re: Attempted roadmap of future instance variables…

Hi –

On Wed, 3 Dec 2003, Steve Tuckner wrote:

So what is the relationship between @_ vars and @vars that
are defined in a
class context (if any)? Is this just to allow easier access
to class local
vars (that you can already define)? Does below describe the
situation
accurately?

I think that @_ and @ variables would behave identically when it came
to Class objects’ instance variables – simply because you can’t
subclass Class, so the issue of whether the same or an old or new
variable is in use would never arise. In other words, the situation
exactly analogous to what I did before would be:

class Class
def m
@var = “hi”
@_var = “hello”
end
end

class B < Class # error
def n
puts @var
puts @_var
end
end

which can never happen.

Also, I assume (and hope :slight_smile: that all of this will still be governed
by the “every object can have its own instance variables” principle.
That means that if an object is a Class, and has its own instance
variables, they will not be directly visible to other objects
(including instances of that class).

Therefore, in your example:

class A
@a = 1 # a is a class local variable
@_a = 2 # a is also a class local variable
@@a = 3 # a is a global variable whose
visibility is itself and its
sub-classes

def A.a		# define to allow access to class's instance var
  @a
end

def display
  puts "a (class local - current) = #{self.class.a}"
  puts "a (class local - new) = #{@_a}"

@_a here would refer to the @_a of an instance of A, not A’s own @_a.
And an instance of A, say ‘a’ in:

a = A.new

is a different object – a different ‘self’ – from A, and therefore
does not have direct lexical access to A’s own instance variables,
only its own.

That, in turn, means you’ve asked it to display an uninitialized
instance variable, so here:

A.new.display
=> a (class local - current) = 1
=> a (class local - new) = 2

you should get nil, not 2.

David


David A. Black
dblack@wobblini.net

So @_var does not refer to the class instance variable @var? If @_var
defined in a class context is different from @_var in an instance then how
does one refer to the @_var created in the instance context in the class
context?

@_var defined in a class context is different from @_var in an instance

      like

@var defined in a class context is different from @var in an instance

See gsub!(/@_/, '@') # :slight_smile:

Guy Decoux

Steve Tuckner wrote:

Maybe I am being dense, so bear with me…

I think David’s logic is impeccable. You cannot subclass
the class Class so the difference of a class instance and a
class local instance variable could never materialize.

You can subclass class Module (with its predefined subclass
Class) btw. so the difference would show up immediately.

/Christoph

Steve Tuckner wrote:

So @_var does not refer to the class instance variable @var?

Correct. @_var and @var refer to two different instance variables.

If @_var defined in a class context is different from @_var in an instance then how
does one refer to the @_var created in the instance context in the class
context?

If I parsed that question correctly, the answer is “you don’t” :wink:

Generally speaking, there isn’t any way for the class of an instance
to refer to its instance’s instance variables.

I would think that @_var in the instance context should be the same as
refering to the @var in the class context. It would be like having
attr_accessor for @var with a little sugar for the instance context.

I’m not sure, but I think you may be under the impression that @_var and
@var are somehow linked to each other, and they aren’t. (Perhaps David
should have used completely different names in the original example).

For C++ programmers, the easiest way to think of this is that a Ruby
instance variable whose name starts with an underscore (such as @_foo)
is private, in the C++ sense. An instance variable whose name doesn’t
start with an underscore (such as @bar) is protected, again in the C++
sense.

Unless, of course, I am completely confused :wink:

I think David's logic is impeccable. You cannot subclass
the class Class so the difference of a class instance and a
class local instance variable could never materialize.

Can you reply to [ruby-talk:87003] ?

Thanks,

Guy Decoux

OK so the jist of it is that @_var variables are stored with the class of
the instance but the class has no access to that. That is all. Right?

Steve Tuckner

···

-----Original Message-----
From: Lyle Johnson [mailto:lyle@users.sourceforge.net]
Sent: Tuesday, December 02, 2003 11:57 AM
To: ruby-talk ML
Subject: Re: Attempted roadmap of future instance variables…

Steve Tuckner wrote:

So @_var does not refer to the class instance variable @var?

Correct. @_var and @var refer to two different instance variables.

If @_var defined in a class context is different from @_var
in an instance then how
does one refer to the @_var created in the instance context
in the class
context?

If I parsed that question correctly, the answer is “you don’t” :wink:

Generally speaking, there isn’t any way for the class of an
instance
to refer to its instance’s instance variables.

I would think that @_var in the instance context should be
the same as
refering to the @var in the class context. It would be like having
attr_accessor for @var with a little sugar for the instance context.

I’m not sure, but I think you may be under the impression
that @_var and
@var are somehow linked to each other, and they aren’t.
(Perhaps David
should have used completely different names in the original example).

For C++ programmers, the easiest way to think of this is that a Ruby
instance variable whose name starts with an underscore (such
as @_foo)
is private, in the C++ sense. An instance variable whose name doesn’t
start with an underscore (such as @bar) is protected, again
in the C++
sense.

Unless, of course, I am completely confused :wink:

ts wrote:

I think David’s logic is impeccable. You cannot subclass the class
Class so the difference of a class instance and a class local
instance variable could never materialize.

Can you reply to [ruby-talk:87003] ?

I guess

“B::m”
“B::_m”
“B::m”
“B::_m”

What would you expect?

/Christoph

Hi,

···

In message “Re: Attempted roadmap of future instance variables…” on 03/12/03, Steve Tuckner STUCKNER@MULTITECH.COM writes:

OK so the jist of it is that @_var variables are stored with the class of
the instance but the class has no access to that. That is all. Right?

No. @_var variables are stored in the instance, but they are
accessible only from methods defined in the same class.

						matz.

I guess

"B::m"
"B::_m"
"B::m"
"B::_m"

What would you expect?

   "B::m"
   "B::_m"
   "B::m"
   nil

Guy Decoux

This is not at all what I expected. :frowning:

Are @_var variables just basically private instance variables (as in private
variables in C++?

Steve Tuckner

···

-----Original Message-----
From: Yukihiro Matsumoto [mailto:matz@ruby-lang.org]
Sent: Tuesday, December 02, 2003 12:20 PM
To: ruby-talk ML
Subject: Re: Attempted roadmap of future instance variables…

Hi,

In message “Re: Attempted roadmap of future instance variables…” > on 03/12/03, Steve Tuckner STUCKNER@MULTITECH.COM writes:

OK so the jist of it is that @_var variables are stored with
the class of
the instance but the class has no access to that. That is all. Right?

No. @_var variables are stored in the instance, but they are
accessible only from methods defined in the same class.

  					matz.

“Yukihiro Matsumoto” matz@ruby-lang.org schrieb im Newsbeitrag
news:1070389195.767662.15370.nullmailer@picachu.netlab.jp…

Hi,

OK so the jist of it is that @_var variables are stored with the class
of
the instance but the class has no access to that. That is all. Right?

No. @_var variables are stored in the instance, but they are
accessible only from methods defined in the same class.

Still a number of questions arise to me: How then are @_ variables treated
with respect to methods instance_variables, instance_variable_set and
instance_variable_get? Are they ignored and there is a second set of
methods that receives the class as argument (e.g.
instance_local_variables, instance_local_variable_get,
instance_local_variable_set)

If so, what, if they are defined in an instance’s private class like this:

class <<obj
def get_foo; @_foo; end
def set_foo(f); @_foo = f; end
end

Do we use the instance instead of the class as method argument to those
methods (see above) to get access to them via those methods? If so, how
is that disambiguited if obj is a class?

Or do we make them unique by modifying the identifier, e.g. @_var becomes
@Foo:_var if it was defined in class Foo?

If we have this second set of methods, it seems to me as if things are
getting overly complex, i.e., away from Ruby’s simplicity. Just my 0.02
cent…

Kind regards

robert
···

In message “Re: Attempted roadmap of future instance variables…” > on 03/12/03, Steve Tuckner STUCKNER@MULTITECH.COM writes:

Steve Tuckner wrote:

This is not at all what I expected. :frowning:

Are @_var variables just basically private instance variables
(as in private variables in C++?

Yes - note however that Ruby’s usage (for methods) of the
attribute “private” is different to C++'s usage - consequently
the original Ruby terminology “private instance variable”
became extinct - until now:-)

/Christoph