Reputation: 6772
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.
Upvotes: 10
Views: 2982
Reputation: 118271
%{..}
,%!..!
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"
>>
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"
Upvotes: 0
Reputation: 160551
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".
Upvotes: 9
Reputation: 23566
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.
Upvotes: 1
Reputation: 25964
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]
Upvotes: 13