[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

=~ and rescue

Patrick Gundlach

10/19/2003 10:27:00 AM

Dear Ruby-Hackers,

i'd like to catch a malformed regular expression like this:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#!/usr/bin/ruby

begin
"abcd" =~ /*foo*/
rescue StandardError
puts "error"
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


The above does not work (-:4: invalid regular expression; there's no
previous pattern, to which '*' would define cardinality at 1: /*foo*/)

How do I catch this correctly?

Patrick
--
pg <at> levana .de
13 Answers

Jason Williams

10/19/2003 11:47:00 AM

0

In article <m2wub1o754.fsf@levana.de>, Patrick Gundlach wrote:
> Dear Ruby-Hackers,
>
> i'd like to catch a malformed regular expression like this:
> "abcd" =~ /*foo*/
> rescue StandardError
> puts "error"
> end

Why would you want to do that? Its an error that can be caught
at compile-time, so why let it go until run-time? You can fool
it into missing the error like this, if you want -

regexString = "*foo*"
begin
"abcd" =~ /#{regexString}/
rescue RegexpError
puts "Oops"
end

....but I don't see what this gains.

Patrick Gundlach

10/19/2003 12:02:00 PM

0

Hi,

> Why would you want to do that? Its an error that can be caught
> at compile-time, so why let it go until run-time?

Because I want to let a user create a regexp and use it in /../.


> You can fool it into missing the error like this, if you want -

[....]

great!

Thank you very much.

BTW: Is there something like a generic Error that can be used with
rescue?

Like

begin
something bad
rescue anyerror
recover
end

Patrick

Patrick Gundlach

10/19/2003 12:25:00 PM

0


ansering my own post...

> BTW: Is there something like a generic Error that can be used with
> rescue?

> Like
>
> begin
> something bad
> rescue anyerror
> recover
> end

I guess it is just rescue without any parameter?

Patrick

meinrad recheis

10/19/2003 12:54:00 PM

0

Patrick Gundlach wrote:

[...]

>
> BTW: Is there something like a generic Error that can be used with
> rescue?

the superclass of all exceptions is Exception.

so:

begin
...
rescue Exception
end

will definitely catch any exceptions thrown between begin and end.

>
> Patrick

-- henon

meinrad recheis

10/19/2003 4:39:00 PM

0

Patrick Gundlach wrote:
[...]

> I guess it is just rescue without any parameter?

No, that rescues just StandardError
>
> Patrick

also, if you get regexp input from your users be aware of the fact,
that a regexp may execute ruby code:

this is a regexp that prints Hello World!

/#{puts 'Hello World!'}/

cheers,
- henon

Patrick Gundlach

10/19/2003 4:57:00 PM

0

Hi,

henon <meinrad.recheis@gmx.at> writes:

> No, that rescues just StandardError

good to know. Next time I should read the pickaxe more carefully.

> also, if you get regexp input from your users be aware of the fact,
> that a regexp may execute ruby code:
>
> this is a regexp that prints Hello World!
>
> /#{puts 'Hello World!'}/

Oh no! Is there any simple way to circumvent this? Or do I have to
analyze (strip #{...} from) the regexp?

Thank you for the important hint.

Patrick

Robert Klemme

10/19/2003 8:09:00 PM

0


"Patrick Gundlach" <clr1.10.randomuser@spamgourmet.com> schrieb im
Newsbeitrag news:m2oewdo2qt.fsf@levana.de...
> Hi,
>
> > Why would you want to do that? Its an error that can be caught
> > at compile-time, so why let it go until run-time?
>
> Because I want to let a user create a regexp and use it in /../.

But then I'd use Regexp.new:

user_regexp = get_input()

begin
rx = Regexp.new( user_regexp, user_set_flags )
rescue RegexpError => e
user_feedback( e )
end

Regards

robert

Patrick Gundlach

10/19/2003 8:44:00 PM

0

Hello again,

henon <meinrad.recheis@gmx.at> writes:

> also, if you get regexp input from your users be aware of the fact,
> that a regexp may execute ruby code:
>
> this is a regexp that prints Hello World!
>
> /#{puts 'Hello World!'}/

But not in this case:

--------------------------------------------------
#!/usr/bin/ruby

malcode="#" + "{ puts 'hallo' }"

puts malcode # prints #{ puts 'hallo' }

"foo" =~ /#{malcode}/ # does not print anything
--------------------------------------------------

Am I safe using the last line?

Patrick

Patrick Gundlach

10/19/2003 8:49:00 PM

0

Hello Robert,


"Robert Klemme" <bob.news@gmx.net> writes:
> But then I'd use Regexp.new:
>
> user_regexp = get_input()
>
> begin
> rx = Regexp.new( user_regexp, user_set_flags )
> rescue RegexpError => e
> user_feedback( e )
> end

I now have

begin
do_something if mystring =~ user_regexp
rescue ....
user_feedback ...
end

what is the advantage of Regexp.new over my approach?

Patrick
--
You are your own rainbow!

Robert Klemme

10/20/2003 7:25:00 AM

0


"Patrick Gundlach" <clr1.10.randomuser@spamgourmet.com> schrieb im
Newsbeitrag news:m2u165lzrp.fsf@levana.de...
> Hello Robert,
>
>
> "Robert Klemme" <bob.news@gmx.net> writes:
> > But then I'd use Regexp.new:
> >
> > user_regexp = get_input()
> >
> > begin
> > rx = Regexp.new( user_regexp, user_set_flags )
> > rescue RegexpError => e
> > user_feedback( e )
> > end
>
> I now have
>
> begin
> do_something if mystring =~ user_regexp
> rescue ....
> user_feedback ...
> end
>
> what is the advantage of Regexp.new over my approach?

irb(main):003:0> "foo" =~ "fo+"
(irb):3: warning: string =~ string will be obsolete; use explicit regexp
=> 0
irb(main):004:0>

IOW, "mystring =~ user_regexp" is not a regexp match if "user_regexp" is
not a regexp string and in future versions it will be only a string match
regardless what kind of string is there in user_regexp.

Regexp.new() is simply the directest way to create a regexp from a string
and also it's faster:

09:23:49 [ruby]: ruby rx-eval.rb
user system total real
eval 2.125000 0.000000 2.125000 ( 2.133000)
direct 1.515000 0.015000 1.530000 ( 1.558000)
09:24:14 [ruby]: cat rx-eval.rb

require 'Benchmark'
include Benchmark

REP = 100000
expr = "fo+"
eval_expr = "/#{expr}/"

bm do |run|
run.report( "eval" ) do
for i in 0...REP
eval eval_expr
end
end

run.report( "direct" ) do
for i in 0...REP
Regexp.new expr
end
end

end
09:24:34 [ruby]:

Cheers

robert