Question

I feel I should preemptively apologize because this seems like the type of question that's probably been asked before. I couldn't find an answer so I'm asking here.

I'm going through the RubyKoans and I'm at line:24 of about_strings.rb There's a test:

def test_use_flexible_quoting_to_handle_really_hard_cases
  a = %(flexible quotes can handle both ' and " characters)
  b = %!flexible quotes can handle both ' and " characters!
  c = %{flexible quotes can handle both ' and " characters}
  assert_equal true, a == b
  assert_equal true, a == c
end

So what exactly is the difference between a, b, and c. Why exactly do three ways of doing something exist? This seems illogical. I know Ruby is flexible but I don't think of it as illogical.

Was it helpful?

Solution 2

Look at other languages and you'll see the same thing.

There are times we need to be able to define a wrapping character that is NOT in the string, and using % allows us to do that. This is a powerful, and very usable, way of avoiding "leaning toothpick syndrome".

OTHER TIPS

There's not three ways, there's... a lot of ways. Any non-alphanumeric character that follows % is a valid delimiter.

%[this is a valid string]
%~this is a valid string~
%+this is a valid string+

etc.

Note that brackets-and-friends are a little special, ruby is smart enough to allow you to use pairs of them - or even nest balanced pairs inside, a la

%[this is a [valid] string]

In Ruby you have "flexible quotes" syntax which is as follow: %[any non-word, non-whitespace character]String[opening character or closing bracket]. So you can use almost any non-word and non-whitespace character as a delimeter.

%{..},%!..! etc are same as %Q{} construct, that means string interpolation will happen. Be careful that the construct %{..},%!..! are not %q{..}.

>> x = 5
=> 5
>> %q[#{x}] # interpolation will not happen
=> "\#{x}"
>> %[#{x}] # interpolation will happen
=> "5"
>> %Q[#{x}] # interpolation will happen
=> "5"
>> 

The % Notation

There is also a Perl-inspired way to quote strings: by using % (percent character) and specifying a delimiting character, for example:

%{78% of statistics are "made up" on the spot}
# => "78% of statistics are \"made up\" on the spot"

Any single non-alpha-numeric character can be used as the delimiter, %[including these], %?or these?, %~or even these things~. By using this notation, the usual string delimiters " and ' can appear in the string unescaped, but of course the new delimiter you've chosen does need to be escaped. However, if you use %(parentheses), %[square brackets], %{curly brackets} or %<pointy brackets> as delimiters then those same delimiters can appear unescaped in the string as long as they are in balanced pairs:

%(string (syntax) is pretty flexible)
# => "string (syntax) is pretty flexible"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top