# Unexpected behaviour of defined? under 1.8.x

**URL:** <https://www.ruby-forum.com/t/unexpected-behaviour-of-defined-under-1-8-x/195413>\
**Category:** Ruby\
**Created:** [September 22, 2010, 11:42pm UTC](https://www.ruby-forum.com/t/unexpected-behaviour-of-defined-under-1-8-x/195413 "2010-09-22T23:42:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![juuser](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/5f8ce5/32.png) [@juuser](https://www.ruby-forum.com/u/juuser)\
**Post date:** [September 22, 2010, 11:42pm UTC](https://www.ruby-forum.com/t/unexpected-behaviour-of-defined-under-1-8-x/195413/1 "2010-09-22T23:42:54Z")

</div>

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:🅱: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:🅱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 P.

---

<div class="post-metadata">

**Author:** ![juuser](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/5f8ce5/32.png) [@juuser](https://www.ruby-forum.com/u/juuser)\
**Post date:** [September 23, 2010, 1:08am UTC](https://www.ruby-forum.com/t/unexpected-behaviour-of-defined-under-1-8-x/195413/2 "2010-09-23T01:08:20Z")

</div>

On Wed, Sep 22, 2010 at 5:35 PM, Jarmo P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> ```
> 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,…

Why?

defined? is there to check WITHOUT raising an runtime error

ruby-1.8.7-p302 \> defined? Blatz  
=\> nil  
ruby-1.8.7-p302 \> defined? A:🅱:C  
=\> nil  
ruby-1.8.7-p302 \> defined? Object  
=\> “constant”

And it’s the same for 1.9.2

ruby-1.9.2-p0 \> defined? Blatz  
=\> nil  
ruby-1.9.2-p0 \> defined? A:🅱:C  
=\> nil  
ruby-1.9.2-p0 \> defined? Object  
=\> “constant”

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Github: [rubyredrick (Rick DeNatale) · GitHub](http://github.com/rubyredrick)  
Twitter: @RickDeNatale  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![juuser](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/5f8ce5/32.png) [@juuser](https://www.ruby-forum.com/u/juuser)\
**Post date:** [September 23, 2010, 10:17am UTC](https://www.ruby-forum.com/t/unexpected-behaviour-of-defined-under-1-8-x/195413/3 "2010-09-23T10:17:47Z")

</div>

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:🅱:C”, then of course A::B has to be autoloaded before you check  
A:🅱: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:🅱:C) # nil  
p defined?(A:🅱:C) # “constant”

---- b.rb ----  
module A  
class B  
puts “Starting”  
C = 123  
raise “Oops”  
puts “Never get here”  
end  
end

---

<div class="post-metadata">

**Author:** ![juuser](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/5f8ce5/32.png) [@juuser](https://www.ruby-forum.com/u/juuser)\
**Post date:** [September 23, 2010, 10:35pm UTC](https://www.ruby-forum.com/t/unexpected-behaviour-of-defined-under-1-8-x/195413/4 "2010-09-23T22:35:39Z")

</div>

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`’

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
