Exception never raised when threading an eval containing a m

Hello everyone!

I’ve encountered a strange issue when coding a tool extending ruby, and
was wondering if I was missing something… I’m working under windows
with
the last stable release of ruby (1.8.5-21) and did not find a way to
debug
ruby sources to observe the behaviour. This is reproductible with just
the
common ruby interpreter. Let me explain the problem :

First let’s consider this small script :

#!/usr/bin/env ruby
$FOO+2

We get the evident result ($FOO is not defined, an exception’s raised) :

test.rb:2: undefined method `+’ for nil:NilClass (NoMethodError)

Then let’s consider this small script :

#!/usr/bin/env ruby
eval("puts “foo”)

You can see that the string given to puts is malformed, so we get again
an
exception :

(eval):1: compile error (SyntaxError)
(eval):1: unterminated string meets end of file

Ok. Now let’s thread this. Let’s consider the following script :

#!/usr/bin/env ruby
def newthread()
toret = Thread.new {
puts “START”
begin
$FOO+2
rescue
puts(“EXCEPTION !!!”)
end
puts “END”
}
return toret
end

$TESTTHREAD = newthread()
2.times {
if(!$TESTTHREAD.alive?) then
puts “DEAD, RESURRECTING”
$TESTTHREAD = newthread()
sleep(4)
end
}

We create a thread, provoke an exception, catch it, restart the thread,
and so on twice again. We get the following expected behaviour :

START
EXCEPTION !!!
END
DEAD, RESURRECTING
START
EXCEPTION !!!
END
DEAD, RESURRECTING
START
EXCEPTION !!!
END

But now, let’s consider this (here comes the issue) : we do exactly the
same thing (we only replace the $FOO+2 line by our malformed eval-puts)
:

#!/usr/bin/env ruby
def newthread()
toret = Thread.new {
puts “START”
begin
eval("puts “foo”)
rescue
puts(“EXCEPTION !!!”)
end
puts “END”
}
return toret
end

$TESTTHREAD = newthread()
2.times {
if(!$TESTTHREAD.alive?) then
puts “DEAD, RESURRECTING”
$TESTTHREAD = newthread()
sleep(4)
end
}

And then we get…

START
DEAD, RESURRECTING
START
DEAD, RESURRECTING
START

(!!) It simply seems that the ruby thread dies inside the eval, and the
exception is never raised (?). Has someone an explanation for this ?
(found a bug somewhere ?) :slight_smile:

Many thanks by advance for those who’d work on that matter!

Ben

On 2/5/07, Benjamin B. [email protected] wrote:

    eval("puts \"foo")
    def newthread()
    end

We create a thread, provoke an exception, catch it, restart the thread,
START
begin
2.times {
DEAD, RESURRECTING
START
DEAD, RESURRECTING
START

(!!) It simply seems that the ruby thread dies inside the eval, and the
exception is never raised (?). Has someone an explanation for this ?
(found a bug somewhere ?) :slight_smile:

Many thanks by advance for those who’d work on that matter!

Hi,

it’s easy:
$FOO+2 raises NoMethodError < StandardError
while eval(…) raises SyntaxError !< StandardError

empty rescue == rescue StandardError

If you want to catch ALL exceptions, use rescue Exception.

For exceptions hierarchy see

For exceptions hierarchy see
Ruby | zenspider.com | by ryan davis

Thanks Jan ! Really easy indeed, and it solved my problem :).

Ben

i need datasheet (schematic) chipset coolsand CT1128, anyone please help
me…

Hi~

On Feb 5, 2007, at 2:04 AM, Benjamin B. wrote:

First let’s consider this small script :

}

}
EXCEPTION !!!
#!/usr/bin/env ruby
return toret

this ? (found a bug somewhere ?) :slight_smile:

Many thanks by advance for those who’d work on that matter!

Ben

Ben-

By default ruby doesn’t propogate exceptions up out of the threads,
if an exception is raised in a thread that thread will just silently
dies. To make exceptions in a thread raise to the top level you need
to set this in your script:

Thread.abort_on_exception = true

Cheers-

– Ezra Z.
– Lead Rails Evangelist
[email protected]
– Engine Y., Serious Rails Hosting
– (866) 518-YARD (9273)