The braceless #@ivar interpolation shorthand
Question
What's the return value of the following Ruby code?
class Hi
def initialize(name)
@name = name
end
def to_s = "Hi #@name"
end
Hi.new("RubyCademy").to_s # => ???
The correct answer is
-
#❮Hi:0x13005 @name="RubyCademy"❯ -
"Hi #@name" -
"Hi RubyCademy"Correct -
nil
Explanation
TL;DR
#@name inside a double-quoted string is a real interpolation, not a literal. Ruby allows the braces of #{...} to be omitted when the interpolated expression is exactly one instance, class, or global variable. So "Hi #@name" is equivalent to "Hi #{@name}" and returns "Hi RubyCademy".
Step by step
class Hi
def initialize(name)
@name = name
end
def to_s = "Hi #@name"
end
Hi.new("RubyCademy").to_s # => "Hi RubyCademy"
initializestores"RubyCademy"in@name.to_sis an endless method whose body is the string literal"Hi #@name".- When the string literal is evaluated, the parser recognizes
#@nameas an interpolation of the instance variable, callsto_son its value, and splices it in.
The shorthand covers exactly three sigils:
@ivar = "instance"
$gvar = "global"
"#@ivar" # => "instance"
"#$gvar" # => "global"
Class variables work the same way: "#@@counter" interpolates @@counter. Local variables, method calls, and any expression more complex than a single variable still require the braces:
name = "local"
"#name" # => "#name" (no interpolation, literal characters)
"#{name}" # => "local"
Edge cases
An uninitialized instance variable evaluates to nil, and nil.to_s is "", so the interpolation silently produces nothing:
"Hi #@missing" # => "Hi "
As with all interpolation, single quotes disable it: 'Hi #@name' contains the literal characters #@name. Most style guides (RuboCop's Style/VariableInterpolation rule included) prefer the explicit #{@name} form: the shorthand is easy to misread as a comment or a literal #, and it breaks as soon as you need @name.upcase instead of @name.
Share this quiz
Comments
No comments yet. Be the first.