What Does This Ruby/RegEx Code Do?
I'm going through Beginning Ruby From Novice To Professional 2nd Edition and am currently on page 49 where we are learning about RegEx basics. Each RegEx snippet in 开发者_JAVA百科the book has a code trailing it that hasn't been explained.
{ |x| puts x }
In context:
"This is a test".scan(/[a-m]/) { |x| puts x }
Could someone please clue me in?
A method such as scan
is an iterator; in this case, each time the passed regex is matched, scan
does something programmer-specified. In Ruby, the "something" is expressed as a block, represented by { code }
or do code end
(with different precedences), which is passed as a special parameter to the method. A block may start with a list of parameters (and local variables), which is the |x|
part; scan
invokes the block with the string it matched, which is bound to x
inside the block. (This syntax comes from Smalltalk.)
So, in this case, scan
will invoke its block parameter every time /[a-m]/
matches, which means on every character in the string between a
and m
.
It prints all letters in the string between a
and m
: http://ideone.com/lKaoI
|x| puts x
is an annonymouse function, (or a "block", in ruby, as far as I can tell, or a lambda in other languages), that prints its argument.
More information on that can be found in:
- Wikipedia - Ruby - Blocks and iterators
- Understanding Ruby Blocks, Procs and Lambdas
The output is
h
i
i
a
e
Each character of the string "This is a test" is checked against the regular expression [a-m]
which means "exactly one character in the range a..m
, and is printed on its own line (via puts
) if it matches. The first character T
does not match, the second one h
does match, etc. The last one that does is the e
in "test".
In the context of your book's examples, it's included after each expression because it just means "Print out every match."
It is a code block, which runs for each match of the regular expression.
{ }
creates the code block.
|x|
creates the argument for the code block
puts
prints out a string, and x
is the string it prints.
The regular expression matches any single character in the character class [a-m]
. Therefore, there are five different matches, and it prints out:
h
i
i
a
e
The { |x| puts x }
defines a new block that takes a single argument named x
. When the block is called, it passes its argument x
to puts
.
Another way to write the same thing would be:
"This is a test".scan(/[a-m]/) do |x|
puts x
end
The block gets called by the scan
function each time the regular expression matches something in the string, so each match will get printed.
There is more information about blocks here: http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html
精彩评论