What are Ruby's numbered global variables
They're captures from the most recent pattern match (just as in Perl; Ruby initially lifted a lot of syntax from Perl, although it's largely gotten over it by now :). $1
, $2
, etc. refer to parenthesized captures within a regex: given /a(.)b(.)c/
, $1
will be the character between a
and b
and $2
the character between b
and c
. $`
and $'
mean the strings before and after the string that matched the entire regex (which is itself in $&
), respectively.
There is actually some sense to these, if only historically; you can find it in perldoc perlvar
, which generally does a good job of documenting the intended mnemonics and history of Perl variables, and mostly still applies to the globals in Ruby. The numbered captures are replacements for the capture backreference regex syntax (\1
, \2
, etc.); Perl switched from the former to the latter somewhere in the 3.x versions, because using the backreference syntax outside of the regex complicated parsing too much. (By the time Perl 5 rolled around, the parser had been sufficiently rewritten that the syntax was again available, and promptly reused for references/"pointers". Ruby opted for using a name-quote :
instead, which is closer to the Lisp and Smalltalk style; since Ruby started out as a Perl-alike with Smalltalk-style OO, this made more sense linguistically.) The same applies to $&
, which in historical regex syntax is simply &
(but you can't use that outside the replacement part of a substitution, so it became a variable $&
instead). $`
and $'
are both "cutesy": "back-quote" and "forward-quote" from the matched string.
The non-numbered ones are listed here:
https://www.zenspider.com/ruby/quickref.html#pre-defined-variables
$1, $2 ... $N
refer to matches in a regex capturing group.
So:
"ab:cd" =~ /([a-z]+):([a-z]+)/
Would yield
$1 = "ab"
$2 = "cd"