On 2003-11-25 at 19:53:09, Piers Cawley wrote:
> Is that how Ruby does it then?

=begin RubyDigression

Ruby's String class has the methods sub (replace once) and gsub
(replace all), which leave the invocant alone and return the
result of the substitution, and sub! and gsub!, which modify the
invocant in place.  These methods may take as a replacement operand a
string, which may contain the metacharacters '\&', '\1', '\2', etc.
to refer to captured subexpressions in the regular expression match
(and which have to be protected from normal interpolation-context
string processing, e.g. by using a single-quoted string instead of
a double-quoted one).  However, instead of passing a replacement
string, you can supply a block which will get executed for each
match, with the captured subexpressions as parameters; this is how
Ruby handles the more complex semantics for which Perl5 substitutions
generally use one or more instances of the /e modifier.

So the Ruby equivalent of this Perl5 code:

        $str =~ s/(foo)/$1tball/g;

is either this:                         

        str.gsub!(/(foo)/, '\1tball')

or this:

        str.gsub!(/(foo)/) {|old| "#{old}tball"}

It is generally agreed that the parameters to the block are insufficient;
the other useful match result values such as $&, $`, $' are not included,
so the block must use those (global!) variables directly if needed;
this is generally considered Bad Form.  For instance, if you remove the
parens from the above, you get this Perl5:

        $str =~ s/foo/$&tball/g;

Which sets off the "oh, no, you used $&!" alarm.  The Ruby equivalent is 
either this:

        str.gsub!(/foo/, '\&tball')

or this:

        str.gsub!(/foo/) {"#{$&}tball"}

The behavior may change in a future revision of Ruby to instead
pass the entire MatchData object which is normally returned by the
String#match method.  str.match(/regex/) is roughly equivalent to Perl5
$str =~ /regex/; the latter syntax also works in Ruby, but instead
of a MatchData object it returns either nil [for no match] or the
character index where the match was found.)

=end RubyDigression

-Mark

-- 
Mark REED                    | CNN Internet Technology
1 CNN Center Rm SW0831G      | [EMAIL PROTECTED]
Atlanta, GA 30348      USA   | +1 404 827 4754

Reply via email to