String interpolation in Ruby

greek_to_roman_gods =
{
zeus: 'Jupiter',
hera: 'Juno',
poseidon: 'Neptune',
hades: 'Pluto',
aphrodite: 'Venus',
ares: 'Mars',
artemis: 'Diana',
athena: 'Minerva',
hermes: 'Mercury',
demeter: 'Ceres'
}

"A heavenly marriage: #{greek_to_roman_gods[:zeus]} and #{greek_to_roman_gods[:hera]}"

format('A heavenly marriage: %s and %s', greek_to_roman_gods[:zeus], greek_to_roman_gods[:hera])
format('A heavenly marriage: %{zeus} and %{hera}', greek_to_roman_gods)

'A heavenly marriage: %s and %s' % [greek_to_roman_gods[:zeus], greek_to_roman_gods[:hera]]
'A heavenly marriage: %{zeus} and %{hera}' % greek_to_roman_gods

# All of them return the same result
=> "A heavenly marriage: Jupiter and Juno"

If you save that file, and run rubocop on that file. You will get the offense Favor format over String#% for line 18-19. Look further into the rubocop gem, it’s coming from  RuboCop::Cop::Style::FormatString

This cop enforces the use of a single string formatting utility. Valid options include Kernel#format, Kernel#sprintf and String#%.

The detection of String#% cannot be implemented in a reliable manner for all cases, so only two scenarios are considered - if the first argument is a string literal and if the second argument is an array literal.

I listed 5 ways to do string interpolation. Let’s go through each of them:

  1. String interpolation in double-quoted string
  2. format with additional arguments
  3. format with a hash argument
  4. String#% with a hash
  5. String#% with an array

The first, and the common one, using the hash symbol in double-quoted string.

"A heavenly marriage: #{greek_to_roman_gods[:zeus]} and #{greek_to_roman_gods[:hera]}"

Then we can go ahead and use sprintf, or there is an alias for that in ruby: format. You can supply a number of variables to replace the %s

format('A heavenly marriage: %s and %s', greek_to_roman_gods[:zeus], greek_to_roman_gods[:hera])

Or you can supply a Hash, and format replace the value of matching hash key:

format('A heavenly marriage: %{zeus} and %{hera}', greek_to_roman_gods)

The last two lines use String#%. Here is the doc:

str % arg → new_str
Format—Uses str as a format specification, and returns the result of applying it to arg. If the format specification contains more than one substitution, then arg must be an Array or Hash containing the values to be substituted. See Kernel::sprintf for details of the format string.

rubocop doesn’t approve using String#% for some stated reason above, then we can change safely to use format instead.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s