2

When I set or get instance variables using some name, for example @foo, I can do something like:

instance_variable_set("@foo", some_value)
...
instance_variable_get("@foo")

But often, I use a variable for the method name, which does not include the @ prefix, so that I end up doing:

method = :foo
...
instance_variable_set("@#{method}", some_value)
...
instance_variable_get("@#{method}")

But since all instance variables are prefixed with @, I think it redundant to have to type "@#{method}" instead of simply typing method. Why are the methods instance_variable_set and instance_variable_get not designed to accept string/symbol without @ as its first argument like this:

method = :foo
...
instance_variable_set(method, some_value)
...
instance_variable_get(method)

where the variable to be actually set will be @foo rather than foo?

Is there any advantage with the way it is?

5
  • 1
    Isn't using instance_variable_(get|set) a code smell? Commented Oct 9, 2011 at 22:34
  • :"hello?" is a valid symbol - is it a valid variable name? Commented Oct 9, 2011 at 22:37
  • @Grimm. It is not. My question was, why is it not designed to automatically prefix the string/symbol with "@". I added examples to make my question clearer. Commented Oct 9, 2011 at 22:45
  • If there are some valid symbols that would be converted into invalid instance variable names, could that be a reason? Commented Oct 9, 2011 at 23:30
  • @Grimm I thought about that, but if it would always be used without @, then there will be no problem. I was wondering why it could not be like attr_(accessor|reader|writer), where you don't put @. Commented Oct 10, 2011 at 0:09

1 Answer 1

3

The reason is, quite simply, that the instance variable is named @foo, not foo. The @ is part of the variable name, just as the $ is part of the global variable name $foo.

The reason that @ is not necessary when calling attr_accessor and friends is because they define attribute methods, so it makes sense to provide the method names, not the variable names.

Of course there is no technical reason instance_variable_set cannot prepend the @ itself. However, the method accepts a symbol that corresponds to the variable name. A symbol by definition represents the identifier with the given name. So the only symbol that corresponds to the instance variable @foo is :@foo. That is why you have to include the @, because we know that :foo does not correspond to any instance variable identifier at all. (And if you supply a string, it will be converted to a symbol internally first.)

Update: In the C Ruby implementation (MRI), there is actually no mention of @ anywhere in the code that handles instance variables. Only the parser knows instance variables start with a @. So it seems that separating code parsing from implementation is another possible reason.

Sign up to request clarification or add additional context in comments.

3 Comments

Maybe this boils down to difference in philosophy.
I think it's more about semantics. Hopefully my updated answer makes it more clear (and also introduces another possible reason).
I am not convinced with your original answer, but the updated part convinces me. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.