Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Unexpected behaviour of defined? under 1.8.x

Reply
Thread Tools

Unexpected behaviour of defined? under 1.8.x

 
 
Jarmo Pertman
Guest
Posts: n/a
 
      09-22-2010
Hello!

I've just landed upon a very interesting landmine by using defined?

Consider the following code:

# a.rb
module A
autoload :B, "b.rb"
end

defined?(A::B::C)
p A::B
p A::B.new.one
p A::B.new.two


# b.rb
module A
class B
puts "loading"
def one; 1; end

raise "no-no-no!"

def two; 2; end
end
end

So, when running a.rb what would you expect?

I would expect defined? line to raise an RuntimeError, but instead i
will see this:
loading
A::B
1
a.rb:8: undefined method `two' for #<A::B:0x49590c0> (NoMethodError)

This happens with 1.8.6 and 1.8.7, but is working as expected with
1.9.1.

In real life the code was something like this:
return unless defined?(A::B.some_method)

During the autoload, there was a ton of require statements of which
one failed with LoadError, but this didn't get raised to the console
and half of the unit-tests were failing. Yes, you guessed it right - i
did spend some amount of time with the debugger

Anyway, i've fixed that line to use respond_to? instead, but it is
still odd behaviour...


Jarmo Pertman
-----
IT does really matter - http://www.itreallymatters.net
 
Reply With Quote
 
 
 
 
Rick DeNatale
Guest
Posts: n/a
 
      09-22-2010
On Wed, Sep 22, 2010 at 5:35 PM, Jarmo Pertman <(E-Mail Removed)> wrote:
> Hello!
>
> I've just landed upon a very interesting landmine by using defined?
>
> Consider the following code:
>
> # a.rb
> module A
> =A0autoload :B, "b.rb"
> end
>
> defined?(A::B::C)
> p A::B
> p A::B.new.one
> p A::B.new.two
>
>
> # b.rb
> module A
> =A0 =A0class B
> =A0 =A0 =A0 =A0puts "loading"
> =A0 =A0 =A0 =A0def one; 1; end
>
> =A0 =A0 =A0 =A0raise "no-no-no!"
>
> =A0 =A0 =A0 =A0def two; 2; end
> =A0 =A0end
> end
>
> So, when running a.rb what would you expect?
>
> I would expect defined? line to raise an RuntimeError,...


Why?

defined? is there to check WITHOUT raising an runtime error

ruby-1.8.7-p302 > defined? Blatz
=3D> nil
ruby-1.8.7-p302 > defined? A::B::C
=3D> nil
ruby-1.8.7-p302 > defined? Object
=3D> "constant"

And it's the same for 1.9.2

ruby-1.9.2-p0 > defined? Blatz
=3D> nil
ruby-1.9.2-p0 > defined? A::B::C
=3D> nil
ruby-1.9.2-p0 > defined? Object
=3D> "constant"



--=20
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/pers...-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

 
Reply With Quote
 
 
 
 
Brian Candler
Guest
Posts: n/a
 
      09-23-2010
Rick Denatale wrote:
>> I would expect defined? line to raise an RuntimeError,...

>
> Why?
>
> defined? is there to check WITHOUT raising an runtime error


I think the point is the autoload stuff.

If you have autoload set up for A::B, and you are checking "defined?
A::B::C", then of course A::B has to be autoloaded before you check
A::B::C. But when an exception is raised in the source file which is
being autoloaded, it just finishes at that point silently, so you end up
with half a file loaded.

Here is another example:

---- a.rb ----
module A
autoload :B, "b.rb"
end

p defined?(A::B::C) # nil
p defined?(A::B::C) # "constant"

---- b.rb ----
module A
class B
puts "Starting"
C = 123
raise "Oops"
puts "Never get here"
end
end
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Jarmo Pertman
Guest
Posts: n/a
 
      09-23-2010
I'm fully aware that it was related with autoload and why the file got
partially loaded, but it was just strange behaviour.

I didn't expect that defined? rescues silently any Exceptions (or is
there anything which isn't rescued?). Considering from the name
"defined?" i thought that it will rescue only NameError (which could
happen only if trying to see if any const/class/module/variable is not
defined), but rescueing everything didn't make sense.

As i pointed out then in 1.9.1 the result is more of an expected:
loading
b.rb:6:in `<class:B>': no-no-no! (RuntimeError)
from b.rb:2:in `<module:A>'
from b.rb:1:in `<top (required)>'
from a.rb:6:in `<main>'

Just checked that 1.9.2 works the same.

Rick, why do you expect it to rescue every Exception? What's your
logic behind that assumption or is it just because you knew that this
is the correct behavior?

Jarmo

On Sep 23, 11:17*am, Brian Candler <(E-Mail Removed)> wrote:
> Rick Denatale wrote:
> >> I would expect defined? line to raise an RuntimeError,...

>
> > Why?

>
> > defined? is there to check WITHOUT raising an runtime error

>
> I think the point is the autoload stuff.
>
> If you have autoload set up for A::B, and you are checking "defined?
> A::B::C", then of course A::B has to be autoloaded before you check
> A::B::C. But when an exception is raised in the source file which is
> being autoloaded, it just finishes at that point silently, so you end up
> with half a file loaded.
>
> Here is another example:
>
> ---- a.rb ----
> module A
> * autoload :B, "b.rb"
> end
>
> p defined?(A::B::C) * # nil
> p defined?(A::B::C) * # "constant"
>
> ---- b.rb ----
> module A
> * class B
> * * puts "Starting"
> * * C = 123
> * * raise "Oops"
> * * puts "Never get here"
> * end
> end
> --
> Posted viahttp://www.ruby-forum.com/.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Unexpected behaviour for dispatching events... Mark Java 4 01-12-2011 04:21 PM
An unexpected visit_decref assertion fail (code works under python2.4, doesn't under 2.5) Joe Ardent Python 1 04-26-2009 04:27 PM
Unexpected behaviour Ioannis Vranos C++ 36 09-24-2004 03:49 PM
ostringstream unexpected behaviour Old Wolf C++ 1 02-04-2004 04:38 AM
unexpected map behaviour Steven Van den Berghe C++ 2 08-28-2003 11:59 AM



Advertisments