begin/rescue for flow control

49 views
Skip to first unread message

Peter Brown

unread,
Apr 8, 2012, 7:46:27 PM4/8/12
to objects-...@googlegroups.com
Hi Avdi, 

I'm curious why you chose to use begin/rescue in the Stubbing out modules example near the beginning of the book. This seems to violate one of the principles in Exceptional Ruby where rescue shouldn't be used for flow control, especially since this isn't an exceptional case. Was it an oversight to not use context.const_defined? or was this intentional? If it was intentional, could you explain why?

begin
  context.const_get(name)
rescue NameError
  context.const_set(name, Module.new)
end

vs

if context.const_defined?(name)
  context.const_get(name)
else
  context.const_set(name, Module.new)
end

Jim Gay

unread,
Apr 8, 2012, 9:29:54 PM4/8/12
to objects-...@googlegroups.com
I thought this was mentioned in the book, but I don't have it in front
of me right now.

Rails models/controllers are lazily loaded, so const_defined? might be
false even though you have a file that defines that constant. If that
constant hasn't been loaded before that check has run, it would call
the const_set instead. Using const_get will attempt to find the class
and load the file if there is one.

--
Write intention revealing code #=> http://www.clean-ruby.com

Jim Gay
Saturn Flyer LLC
571-403-0338

Peter Brown

unread,
Apr 8, 2012, 9:45:55 PM4/8/12
to objects-...@googlegroups.com
Hi Jim,

Thanks for the reply. Reading that section again, it makes perfect sense that autoloaded modules wouldn't work. Thanks!

- Pete


On Sunday, April 8, 2012 9:29:54 PM UTC-4, Jim Gay wrote:
I thought this was mentioned in the book, but I don't have it in front
of me right now.

Rails models/controllers are lazily loaded, so const_defined? might be
false even though you have a file that defines that constant. If that
constant hasn't been loaded before that check has run, it would call
the const_set instead. Using const_get will attempt to find the class
and load the file if there is one.

Avdi Grimm

unread,
Apr 8, 2012, 10:51:39 PM4/8/12
to objects-...@googlegroups.com
On Sun, Apr 8, 2012 at 9:29 PM, Jim Gay <j...@saturnflyer.com> wrote:
> Rails models/controllers are lazily loaded, so const_defined? might be
> false even though you have a file that defines that constant.

Bingo. Ruby's autoload has a way to ask if a constant can be
autoloaded, and I assume Rails' method does as well; ;but I wasn't
sure how reliable they are. I figured by actually letting Ruby try to
access the constant I'd be giving any autoload mechanisms the maximum
opportunity to work before falling back on a stub.

--
Avdi Grimm
http://avdi.org

I only check email twice a day. to reach me sooner, go to
http://awayfind.com/avdi

Steve Tooke

unread,
Apr 17, 2012, 4:29:58 PM4/17/12
to objects-...@googlegroups.com
On 9 April 2012 03:51, Avdi Grimm <av...@avdi.org> wrote:
> Bingo. Ruby's autoload has a way to ask if a constant can be
> autoloaded, and I assume Rails' method does as well; ;but I wasn't
> sure how reliable they are. I figured by actually letting Ruby try to
> access the constant I'd be giving any autoload mechanisms the maximum
> opportunity to work before falling back on a stub.

Interesting. When I need a stub Constant defined in my isolated tests
recently I've been using

Constant ||= Class.new

This has seemed to work fine whether I'm running the test in
isolation, or as part of a full test run - whether I'm stubbing an
ActiveRecord class or not!

I guess this is achieving the same thing. It give ruby the chance to
autoload the constant if it knows how to, otherwise it assigns it a
new class (or module or I suppose even an rspec stub).

Steve
--
Steve Tooke :: heavi.es
+44 7919 337 463 :: +44 20 8133 4134
skype:stevetooke :: twitter.com/tooky

Heavies Limited
Registered Number: 7612561
Registered Address: Parmenter House, 57 Tower Street, Winchester SO23 8TD

Reply all
Reply to author
Forward
0 new messages