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?
The reason is, quite simply, that the instance variable is named
@foo, notfoo. 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 callingattr_accessorand 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_setcannot 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@foois:@foo. That is why you have to include the@, because we know that:foodoes 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.