Nat Pryce <nat.pryce / b13media.com> wrote:

> Definitely use self.stuff to avoid breaking encapsulation.

> Imagine if the class was instead:

>   def stuff=(x)
>      @thing = x + 1
>   end
>  
>   def stuff
>      @thing - 1
>   end

> Using @thing as a synonym for self.stuff would give the wrong result.

Hi Nat,

Actually an answer like this is what I am waiting for.  There are other
answers such as "it depends" and "no concensus", but this particular
answer is in my opinion the most interesting because it may actually deny
the need for the existence of two distinct types of instance variables
("protected" variables and "private/local" variables).

From the interface point of view, I agree that using "self.stuff" is
better than using "@thing", because then the derived class needs not be
changed if there is a change in the parent class in the
implementation of "stuff".  In this sense we separate the interface from
its implementation.  Well, it may look "silly" to do "def 
thing; @thing; end", but as Ruby already incurs some overhead as compared
to C, probably the gain in software robustness is more than the relative
loss in code performance (more on this later).

I know that this will break a lot of existing Ruby codes, but suppose now
every Rubyist agrees to use "self.stuff" instead of "@thing" in a derived
class.  Then the Ruby internal can actually be changed so that every
instance variable is private/local to the class.  Access for the child
classes is simply controlled by providing or not providing a *protected*
method such as "stuff" in above.  With this, there will be no need for two
different kinds of instance variables; all instance variables are private, and
"protected" variables are emulated through the use of protected methods.

Next, regarding the need for "protected\n attr_accessor :thing".  If
the concern is efficiency, people can always transform it into C.  For
example, in my simulation case, for efficiency reason, the fundamental
objects' attributes are not actually stored as instance variables but as C
struct members (so that when we are completely in C there is no
performance penalty).  Therefore, for each attribute, a child class has
actually to use "self.thing" instead of "@thing" (because "@thing" simply
does not exist at all).

As I already mentioned, the only drawback is the backward
compatibility.  However, if people can start accessing a parent class
attribute using "self.thing" instead of "@thing", probably at some point
in the future we can by default make all instance variables
private/local.  (Well, if it cannot be done, probably this is an idea for
a new programming language?)

Regards,

Bill