The Ultimate Guide to General Delimited Input
Although my heart belongs to ruby, lately, I haven’t been using it at all– I’ve been working on coding tumblr the game in entirely client side JavaScript. To keep my ruby skills fresh though, I’ve been doing a reading about Ruby on the side. One topic, which I hardly gave any thought to before, has captured my attention: Ruby’s general delimited input, otherwise known as “percent literals” or “percent notation”.
The provenance of these macros is unknown to me. Originally, I ran across to these as “shorthand” which seemed like an odd moniker to me– they’re not at all shorter than the regular syntax. Suggestions online include that these are another of Ruby’s inscrutable Perlisms, like those weird Perl-style global variables, but the only references to them are in the context of Ruby! I can only conclude that they’ve nothing to do with Perl, and that’s a myth perpetuated by Rubyists.
General delimited input notation is defined directly in MRI’s parse.y, and it’s present as far back as version 1.0 from 1996, so it’s likely just sprung from the head of Matz and not a feature cribbed from another language as some people suggest. Whatever its origins, GDI has its uses.
All forms of GDI come in the same basic syntax: %(some modifier) (some delimiter) (your content) (that delimiter)
There are six modifiers for GDI, and some of those have both interpolated and non-interpolated versions. For delimiters, you can use any non-alphanumeric symbol (in the past, you could use alphanumeric ones too, but that’s a terrible practice.) Most commonly, you’ll see people use %Q{curly brackets}
, %Q(parentheses)
, %Q<these pointy things>
, and %Q[square brackets]
, but you can use tildes and even quotation marks, for extra confusion. I’d advise against it, though.
%W"wait can you even do this?"
=> ["wait", "can", "you", "even", "do", "this?"]
Ruby style guides usually advocate the use of parentheses, except in the case of regular expressions, where they advocate curly brackets (since parentheses are very common in RE.)
Contrary to popular belief, one can use your same delimiters unescaped within the GDI, so long as you balance them. So this is fine: %Q{I like braces like these:{} }
But this is not %Q{I only prefer a single brace:{ }
At that point, you should escape that poor brace.
%q / %Q
%q is a macro for a single quote non-intepreted string, and %Q is a macro for a double quote interpreted string. Consequentially, in the former you don’t need to really escape any characters– it’s good for strings with both quotation marks. In the latter, you can use string interpolation, so it’s good for strings with both interpolation and double quotes.
If you don’t use a modifier, for example, %(hello)
, it’s a shorthand for %Q.
```
%Q( Daria said, “Can you do this math?: #{1+2}” )
=> “ Daria said, "Can you do this math?: 3" “
%q( Quinn said, “I cannot do this math: #{1+2}” ) => “ Quinn said, "I cannot do this math: #{1+2}" “
%( Jane said, “I can do this math: #{1+2}” )
=> “ Jane said, "I can do this math: 3" “
### %x
%x uses the \` method and runs its contents as a command in a subshell. Use \` unless your command contains that symbol.
%x(ruby –copyright)
=> “ruby - Copyright (C) 1993-2014 Yukihiro Matsumoto\n”
### %r
%r creates an interpolated regex, but the usual syntax of `/regex/` does as well. Use it if your regex has more than one /.
%r(^Adventure\s?Time$)
=> /^Adventure\s?Time$/
### %w / %W
Ruby 1.1 added %w and %W, which are likely the most common form of GDI you'll find in the wild. It's easiest to think of them as a "word array" or a "whitespace-delimited array", if you're pedantic. It creates an array of strings as separated by the whitespace.
%W( 1 2 3 4 5 #{1+5} )
=> [“1”, “2”, “3”, “4”, “5”, “6”]
%w( 1 2 3 4 5 #{1+5} )
=> [“1”, “2”, “3”, “4”, “5”, “#{1+5}”]
### %s
Introduced in Ruby 1.8, lord knows why this exists-- nobody really uses it. %s creates a single symbol, with whitespace in tact. One might be tempted to use it for symbols with whitespace in it, but the preferred method is by using quotes after `:`, like so: `:"this works"`.
%s(this is useless)
=> :”this is useless”
### %i / %I
The latest modifier for GDI, introduced only in Ruby 2.0, this is the cousin to %w and %W, but instead of an array of strings, these create arrays of symbols. As usual, %i is non-interpolated and %I is interpolated.
Be warned, that the interpolated form creates an extra string on the heap for each symbol. How often do you really want an interpolated symbol, anyways?
fruit = “apple”
%I(banana orange carrot #{fruit})
=> [:banana, :orange, :carrot, :apple]
%i(banana orange carrot #{fruit}) => [:banana, :orange, :carrot, :”#{fruit}”] ```
Conclusions
In general, GDI has its pros and cons: on the one hand, you can use GDI to avoid escaping literals– if you use a lot of quotation marks and other symbols, it can be significantly less confusion to read.
Subscribe via RSS