95

The proper way to use string interpolation in Ruby is as follows:

name = "Ned Stark"
puts "Hello there, #{name}" #=> "Hello there, Ned Stark"

That is the way I intend to always use it.

However, I've noticed something odd in Ruby's string interpolation. I've noticed that string interpolation works in Ruby without the curly braces in regards to instance variables. For example:

@name = "Ned Stark"
puts "Hello there, #@name" #=> "Hello there, Ned Stark"

And that trying the same thing as a non-instance variable does not work.

name = "Ned Stark"
puts "Hello, there, #name" #=> "Hello there, #name"

I've tried this with success in both 1.9.2 and 1.8.7.

Why does this work? What is the interpreter doing here?

Matthew Simoneau
  • 6,199
  • 6
  • 35
  • 46
Charles Caldwell
  • 16,649
  • 4
  • 40
  • 47

1 Answers1

111

According to The Ruby Programming Language by Flanagan and Matsumoto:

When the expression to be interpolated into the string literal is simply a reference to a global, instance or class variable, then the curly braces may be omitted.

So the following should all work:

@var = "Hi"
puts "#@var there!"  #=> "Hi there!"

@@var = "Hi"
puts "#@@var there!" #=> "Hi there!"

$var = "Hi"
puts "#$var there!"  #=> "Hi there!"
tsherif
  • 11,502
  • 4
  • 29
  • 27
  • 4
    Cool question, btw. It's nice to go back and find the little corners of the language I had forgotten about. – tsherif Apr 10 '12 at 15:45
  • 2
    Though your answer doesn't contain a reason why or what is going on, I'm finding that the reason is hard to nail down. Even the old message boards Matz commented on frequently are not helping. However, your answer shows it is a feature as opposed to just a fluke. – Charles Caldwell Apr 10 '12 at 16:04
  • 1
    I'm not sure what you're expecting as a reason though. Do you mean as a design decision? My guess would be that it was an attempt at *Perl-like* syntax, since I believe Ruby was originally conceived as a sort of Perl++ before coming into its own. – tsherif Apr 10 '12 at 16:13
  • 1
    Cool, Don't use {} around instance variables being interpolated into a string. https://github.com/bbatsov/ruby-style-guide – Cam Song Oct 09 '12 at 15:17
  • 3
    I'm a complete noob and just had my IDE complain about me doing this. But I'm having a hard job convincing myself that it's good style. It's pointlessly inconsistent and has a downside - e.g. if I have an instance variable @distance with value 100 and want to make a string that says something like "100m" using an expression like "#@distancem" I'll just get a blank string because there's no instance variable 'distancem'. So this sounds like outright bad style. – terriblememory Dec 13 '12 at 18:13
  • 5
    @terriblememory Oh it is definitely bad style. That's why I started my question by pointing out the correct way of doing it. However, I just found it odd that it was a feature of the language at all and wondered why it worked. Then again, it is also bad style to start a sentence with a conjunction. But you will still see people using it here and there. =) – Charles Caldwell Jan 25 '13 at 13:54
  • I suspect the _reason_ is that those variable types each have a prefix. That way the interpreter knows its interpolating when it sees "#{", "#@", "#@@", or "#$" but it cannot distinguish "#name" from "we're #1", or "#firstworldproblems". – Joe Flynn May 15 '13 at 17:09
  • 1
    @CamSong the advice was [reversed](https://github.com/bbatsov/ruby-style-guide/commit/21a8b5bd596bd6d67f3035fd1c885cfd5b3663e5): *Don't leave out `{}` around instance and global variables being interpolated into a string.* – Stefan Nov 30 '13 at 12:04
  • Well it's the same in `bash`, you can use `$var` or `${var}`. You usually use the shorter and less ugly variant, but when needed use the long form. To me the ruby choice of `#{}` is rather ugly. – akostadinov Mar 19 '14 at 11:41
  • i'm pretty sure that one is an interpolation of variables, and the other is the interpolation of code. But the interpolation of code is the more general way of doing things, and has the other advantage of having the separator from the rest of the string built in. So most people just use the #{} syntax. Perhaps if there is no compiler optimization the #@var way is faster (just a variable lookup, and not an anonymous function call. – Gerard ONeill Dec 04 '16 at 14:40