The Pickaxe doc for String#sub states the MatchData $-variables will be available using the block form of String#sub!, but it doesn't bother to remind you that they are available in the non-block form as well.
"Jos Backus" <jos@catnook.com> schrieb im Newsbeitrag news:20050209201021.GA47301@lizzy.catnook.com...
Given Perl's
$_ = "123 foo";
s/^(\d+)\s+//;
$pid = $1;
print "$_\n$pid\n";
all I can come up with is
line = "123 foo"
pid = nil
line.sub!(/^(\d+)\s+/) {pid = $1; ''}
puts line, pid
Is there a better way perhaps?
Others have shown ways to mimic Perl - even so far as to include the trailing semicolons. I don't know why you want to mimic Perl, but here's how I'd do it in Ruby:
if /^(\d+)\s+(.*)$/ =~ str
pid, name = $1, $2
else
# no match
end
Duh, for some reason I didn't realize that $1 etc. are available _outside_ the
block in the first place as they are global.
Thanks for all your responses people, enlightening as always.
···
On Thu, Feb 10, 2005 at 05:52:34AM +0900, Glenn Parker wrote:
The Pickaxe doc for String#sub states the MatchData $-variables will be
available using the block form of String#sub!, but it doesn't bother to
remind you that they are available in the non-block form as well.
--
Jos Backus _/ _/_/_/ Sunnyvale, CA
_/ _/ _/
_/ _/_/_/
_/ _/ _/ _/
jos at catnook.com _/_/ _/_/_/ require 'std/disclaimer'
One thing I've wondered about: is this thread safe? Is there a chance
that between the first and second statements something will change the
result of the global variables?
I tend to use the more verbose:
.. pid, name = str.match(/^(\d+)\s+(.*)$/).captures
or
.. pid, name = str.scan(/^(\d+)\s+(.*)$/).flatten
Isn't it too bad a non-match raises an IndexError instead of returning nil?
irb(main):006:0> if str[/(hello)/, 1] = ""; puts "match", $1; end
match
hello
=> nil
irb(main):007:0> if str[/(hallo)/, 1] = ""; puts "match", $1; end
IndexError: regexp not matched
from (irb):7:in `='
from (irb):7
irb(main):008:0>
···
On Thu, Feb 10, 2005 at 06:25:06AM +0900, Florian Gross wrote:
--
Jos Backus _/ _/_/_/ Sunnyvale, CA
_/ _/ _/
_/ _/_/_/
_/ _/ _/ _/
jos at catnook.com _/_/ _/_/_/ require 'std/disclaimer'
One thing I've wondered about: is this thread safe? Is there a chance
that between the first and second statements something will change the
result of the global variables?
They are thread-global variables. The same applies for $_.
I still prefer this form for complex matches, though:
if md = re.match(str) then
capture1, capture2 = md.captures
...
end
Isn't it too bad a non-match raises an IndexError instead of returning nil?
irb(main):006:0> if str[/(hello)/, 1] = ""; puts "match", $1; end
match
hello
=> nil
irb(main):007:0> if str[/(hallo)/, 1] = ""; puts "match", $1; end
IndexError: regexp not matched
from (irb):7:in `='
from (irb):7
irb(main):008:0>
Not sure why you'd want to do that (.slice!() works better IMHO), but perhaps you can do it like this: