Search code examples
rubystringformattingstring-formattingstring-interpolation

Ruby format string with variable inside quotes


If I do

template_string = "class=btn submit-button %<additional_classes>"
format(template_string, additional_classes: 'some-class')

it works. However, if I do

template_string = "class='btn submit-button %<additional_classes>'"
format(template_string, additional_classes: 'some-class')

it fails, giving

ArgumentError:
  malformed format string - %'

(Notice the quotation marks surrounding the classes in the second template_string - this is the only difference between the two blocks of Ruby code). How do I make it work? In other words, how do I produce the following?

class='btn submit-button some-class'

I don't believe that I can just use interpolation, because sometimes I need to pass in other variables. In other words, I can't do

additional_classes = 'some-class'
"class='btn submit-button #{additional_classes}'"

because sometimes I want to reuse the same string "template" but pass in other variables, to produce strings such as the following:

class='btn submit-button some-other-class'

or

class='btn submit-button some-third-class'


Solution

  • From the fine manual:

    format(format_string [, arguments...] ) → string
    [...]
    For more complex formatting, Ruby supports a reference by name. %<name>s style uses format style, but %{name} style doesn't.

    The documentation isn't as clear as it could be but when you use the %<...> form, it is expecting to see %<name>s where name is the hash key and s is the format type: s for string, d for number, ... If you say:

    %<additional_classes>'
    

    then format will try to interpret ' as a type when there is no such type specifier so you get an ArgumentError because the format string is malformed.

    You probably want to use the %{...} form instead:

    template_string = "class='btn submit-button %{additional_classes}'"
    #--------------------------------------------^------------------^