Preferred Instance Variable Access Method

What’s the preferred way of accessing a class’s instance variables?
Almost every example I’ve seen uses the @ form:

class Test
def var_set
@var = 3
end
def var_modify(v)
@vare = 34
return @var
end
end

t = Test.new
t.var_set
puts t.var_modify

The obvious problem with this can be seen in Test#var_modify. The
programmer meant to change the value of @var but made a typo and broke
his code. The program prints 3 instead of 34.

The way around this is through accessors:

class Test
attr_accessor :var
def var_set
self.var = 3
end
def var_modify
self.vare = 34
return self.var
end
end

This produces an error that can be caught.

My question is this: why is this form so rarely used? Is it the extra
typing? Is it somehow un-Rubyesque? It seems like a good way to
catch silly errors like the one above.

Thanks,
Bill

Hi --

What's the preferred way of accessing a class's instance variables?
Almost every example I've seen uses the @ form:

class Test
    def var_set
        @var = 3
    end
    def var_modify(v)
        @vare = 34
        return @var
    end
end

t = Test.new
t.var_set
puts t.var_modify

The obvious problem with this can be seen in Test#var_modify. The
programmer meant to change the value of @var but made a typo and broke
his code. The program prints 3 instead of 34.

The way around this is through accessors:

class Test
    attr_accessor :var
    def var_set
        self.var = 3
    end
    def var_modify
        self.vare = 34
        return self.var
    end
end

This produces an error that can be caught.

My question is this: why is this form so rarely used? Is it the extra
typing? Is it somehow un-Rubyesque? It seems like a good way to
catch silly errors like the one above.

I'm a little puzzled by your example.... Did you mean var_modify to
take an argument? (It does in your first example, though the argument
isn't used.)

Assuming you do mean "def var_modify(v); self.var=v; end" .... That
is indeed somewhat unidiomatic. From the point of view of the calling
code, it's more idiomatic to do:

   obj.var = 100

than

   obj.var_modify(100)

In fact it's so Rubyesque that Matz has provided the attr_* family of
method-writing shortcuts :slight_smile: Wrapping them in further layers of set/get
methods is redundant.

As for the error -- there's no more or less danger here than in many
other places where you use variable names. Consider this:

  def blah(x)
    y = 1
    if x > 5
      return y
    else
      return yy * 2
    end
  end

Of course yy is a typo, but you'll never know until you call the method
with x <= 5.

That (among other reasons) is why there's so much emphasis placed in the
Ruby community on unit testing.

David

···

On Thu, 8 Apr 2004, Bill Atkins wrote:

--
David A. Black
dblack@wobblini.net

Hi,

What’s the preferred way of accessing a class’s instance variables?

I tend to use @var instead of self.var (I guess var() would work, and
var too).

I see two advantages:

  1. Faster (I never benchmarked however)
  2. Lines starting with @ are like methods with ! at the end =>
    Draw the attention to probable side effect on obj’s state.

I do agree that typos can be an issue. There is warning however,
with ruby -w (that sometimes warns for some valid constructions
of mine, I guess defined? could help me avoid that).

Refering to a recent thread, I may add that self.var seems slightly
Python-ish.

I would personally prefer .var but languages with configurable style/
syntax are rare these days (missing C’s #define).

Nota: Ruby let you add instance variables on the fly, such variables
default to nil. Maybe some “strict” pragma/hint would be welcome, paving
the way to some optimization where access to instance variables could
be direct versus thru an hash.

FWIW

Jean-Hugues

EOM

···

At 05:34 08/04/2004 +0900, you wrote:

At 05:34 08/04/2004 +0900, you wrote:

What’s the preferred way of accessing a class’s instance variables?
Almost every example I’ve seen uses the @ form:

class Test
def var_set
@var = 3
end
def var_modify(v)
@vare = 34
return @var
end
end

t = Test.new
t.var_set
puts t.var_modify

The obvious problem with this can be seen in Test#var_modify. The
programmer meant to change the value of @var but made a typo and broke
his code. The program prints 3 instead of 34.

The way around this is through accessors:

class Test
attr_accessor :var
def var_set
self.var = 3
end
def var_modify
self.vare = 34
return self.var
end
end

This produces an error that can be caught.

My question is this: why is this form so rarely used? Is it the extra
typing? Is it somehow un-Rubyesque? It seems like a good way to
catch silly errors like the one above.

Thanks,
Bill


Web: @jhr is virteal, virtually real
Phone: +33 (0) 4 92 27 74 17

Hi,

What’s the preferred way of accessing a class’s instance variables?

I tend to use @var instead of self.var (I guess var() would work, and
var too).

I see two advantages:

  1. Faster (I never benchmarked however)
  2. Lines starting with @ are like methods with ! at the end =>
    Draw the attention to probable side effect on obj’s state.
3) Avoids setting local variables when you wanted to call a writer.

I do agree that typos can be an issue. There is warning however,
with ruby -w (that sometimes warns for some valid constructions
of mine, I guess defined? could help me avoid that).

Refering to a recent thread, I may add that self.var seems slightly
Python-ish.

Without self., ruby may create a local variable rather than call the
writer method when assigning:

class Foo
attr_accessor :bar

def initialize
@bar = “#bar= not called yet”
end

def meth
bar = “#bar= called”
puts self.bar
end
end

Foo.new.meth # => #bar= not called yet

···

Jean-Hugues ROBERT (jean_hugues_robert@yahoo.com) wrote:

At 05:34 08/04/2004 +0900, you wrote:

I would personally prefer .var but languages with configurable style/
syntax are rare these days (missing C’s #define).


Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

Hi –

Jean-Hugues ROBERT jean_hugues_robert@yahoo.com writes:

Hi,

What’s the preferred way of accessing a class’s instance variables?

I tend to use @var instead of self.var (I guess var() would work, and
var too).

I see two advantages:

  1. Faster (I never benchmarked however)
  2. Lines starting with @ are like methods with ! at the end =>
    Draw the attention to probable side effect on obj’s state.

Don’t forget, though, that these techniques (@var vs. self.var) are
only equivalent in certain simple (and common, but not unique) cases.
If you’re doing anything more complex, like:

def var=(x)
@var = x.to_s.upcase
end

then you don’t have a choice; you have to go through the method
(self.var = y) rather than just doing @var = y, elsewhere in the
class.

(The original question involved another level of remove (wrapping the
attr_* methods themselves in “var_get” and “var_modify” methods, but
wherever they occur, @var = and self.var= are not automatically
equivalent.)

This also points to a constraint on Eric’s point about not wanting to
worry about forgetting the ‘self’ – namely, that you can only do that
when you know for sure that #var= is a simple set method for @var.
Also, the @var = y technique could come back to bite you if you
reimplement the setter method and haven’t routed your assignments
through it:

attr_accessor :var
def initialize(y)
@var = y # OK until you reimplement #var= to do something
end # non-simple, at which point you have to remember
# that you assigned directly to @var here.

(I would have quoted Eric directly except I’m posting directly to
comp.lang.ruby, because of the gateway problems, and Eric’s posts
don’t seem to be making it here :frowning:

David

···

At 05:34 08/04/2004 +0900, you wrote:


David A. Black
dblack@wobblini.net