I’m quite taken with ruby, but recently I ran into trouble using grep. I
have two questions: first, is there a way to call grep with multiple
regexps? For example, if you had
ar = [“cat”, “dog”, “smallcat”]
and you only wanted strings matching both “small” and “cat”, in perl I
think you could do something like
ar2 = grep(( /cat/ and /small/ ), ar );
To make this run I had to add some $ signs in front of your variable names
The reason this works in Perl is because you are doing two separate regexp
comparisons. The syntax
/foo/
is shorthand for
$_ =~ /foo/
and ‘grep’ assigns $_ for each iteration, making it like a block parameter
in Ruby. So the direct Ruby translation is
ar2 = ar.select(|e| e =~ /cat/ and e =~ /small/)
In Perl you drop the ‘|e| e=~’ because it’s implicit on $_
There are many Ruby methods which try to simulate this behaviour on $_ by
being methods of Kernel, for example Kernel#chomp! is essentially $_.chomp!,
and because Kernel is included in Object, you can just write ‘chomp!’
But this doesn’t work for a standalone regular expressions. In Ruby you
definitely don’t want /foo/ to mean $_ =~ /foo/, because
myregexp = /foo/ # build a regexp object
is useful and definitely not the same as
myregexp = $_ =~ /foo/ # build and match a regexp object
Personally I think Ruby borrows too much from Perl already in this way; I
would happily see $_ stricken from the language completely, and all the
polluted methods in Kernel removed.
In other words, I’d deprecate
while gets
chomp!
gsub!(/foo/,‘bar’)
# etc
end
in favour of:
while line = gets
line.chomp!
line.gsub!(/foo/,‘bar’)
# etc
end
Somebody once did propose, and I think even implement, a default object
receiver: something like
while line = gets
with line do
chomp!
gsub!(/foo/,‘bar’)
# etc
end
end
For the duration of the block, self is set to ‘line’. That IMO is much
more Rubyish than having a bunch of methods all act on the shared global
variable $_
Anyway, I digress
ar2 = grep(( /cat/ and !/small/ ), ar );
but ‘!’ doesn’t work for me in ruby.
There is
e !~ /foo/
which is shorthand for
!(e =~ /foo/)
Regards,
Brian.
···
On Thu, Apr 24, 2003 at 08:00:55AM +0900, Krishna Dole wrote: