Search code examples
rubystring-formatting

Why does a formatted string with no keys return itself?


Considering this Ruby code:

format_string = "%{greeting}, %{name}"

puts format_string %{greeting: "Hi", name: "John"}  # <-- returns "Hi, John"
puts format_string                                  # <-- returns "%{greeting}, %{name}" 
puts format_string %{greeting: "Hi"}        # <-- returns key{name} not found (KeyError)"

The following code produces an error because it is missing a key.

puts format_string %{greeting: "Hi"}    # returns "key{name} not found (KeyError)"

While the code below returns the exact value of the format_string variable, even though it missing both keys. I would expect the value to be equal to nil, or result in an error like the code above.

puts format_string      # returns "%{greeting: "Hi", name: "John"}"

I'm looking for an explanation of how and why the exact value is returned, when no keys or variables are set to the string. I have read through the ruby docs and multiple web pages relating to ruby formatting, yet I have not been able to find an answer.


Solution

  • Your:

    puts format_string
    

    prints format_string because that's what puts does. The formatting (and complaining about missing keys) that you're seeing is done by the String#% method; puts doesn't interpret the %{...} things in the string, the % operator does that. Perhaps breaking it into two steps (and being more consistent with your whitespace) will clarify things for you:

    formatted_string = format_string % {greeting: "Hi", name: "John"}
    # -------------------------------^ Just an operator like any other, %{ has no special meaning outside the string you use the % operator on.
    puts formatted_string
    

    The % in format_string % hash is just an operator like any other, %{ has no special meaning outside the string you use the % operator on so removing the space between the operator (%) and the opening brace ({) of the hash operand is misleading.