The core of the problem that class local instance variables are trying
to solve is variable shadowing (as Guy so elegantly showed). The
problem with making all variables class local and using accessors, is
that if I am shadowing an instance variable, there is a good chance
that I will shadow the accessor as well. The superclass variable thus
becomes completely inaccessible:
pretend all instance variables are class local
class A
attr_accessor :a
def initialize
@a = 1
end
end
class B < A
attr_accessor :a
def initialize
@a = 'a'
end
end
There is no way for the subclass to access the superclass’s instance
variable @a now, and I don’t see a good work-around for this.
Personally I don’t like any proposal I’ve seen for this concept yet
(including Matz’). I understand that sometimes there are name clashes
when we’d rather there not be, but every cure I’ve seen seems to be
much worse than the disease, cutting down on the flexibility one
currently has in Ruby to easily access anything that one needs to get
the job done. Yes, as things stand now, it is possible to shoot oneself
in the foot, but there are plenty of other ways to do that, and I don’t
think we’re going to remove all of them in Ruby 2.0. I just know that
I’m going to subclass a framework class in Ruby someday and find that
the one variable that I need to change the value of is a class local
instance variable, and I can’t get access to it. Gives me Java
flashbacks.
I wonder if a better solution for the issue doesn’t lie in the idea of
namespaces. Basically, library writers want to be able to say that
@checkpoint is part of the Transaction::Simple namespace, and
occasionally library users want to say that they want to read or write
@checkpoint in the Transaction::Simple namespace. If there was a way to
explicitly limit the namespace of an instance variable to a given Class
or Module, and a way to access an instance variable in an explicit
Class or Module, that would be quite handy. The key is that all data
remains accessible all the time, to everyone. We just allow folks the
ability to shadow.
Stupid, off the top of my head, code example:
module Transaction::Simple
def initialize
namespace self do
@checkpoint = true
end
end
end
class MyClass
include Transaction::Simple
def initialize
@checkpoint = true
namespace Transaction::Simple do
@checkpoint = false
end
end
end
This is definitely half-baked, but perhaps it will trigger something in
someone’s (read Matz’
brain.
Nathaniel
<:((><
···
On Dec 5, 2003, at 12:15, Yukihiro Matsumoto wrote:
Hi,
In message “Re: Attempted roadmap of future instance variables…” > on 03/12/06, “T. Onoma” transami@runbox.com writes:
Wouldn’t it be better just to have instance vars (@foo) local to the
class.
Then subclasses and superclasses (and reportedly singletons too)
would have
to go through accessor methods? Just seems like a simpler and more
elegant
solution. Or is there a problem with this that I’m not seeing
(besides “back
breaking” compatability)?
That would be interesting alternative idea. I think it’s matter of
how much compatibility we would preserve.