Should a Class return an exception or nil on failure to create?

K

_Kevin

Suppose I've written a class that does something useful.

This class, let's call it a Widget, is created like this...

a = Widget.new(some_value)

Not all values of 'some_value' are valid and I need to indicate when
creation fails.
I see two ways to signify this...

a = Widget.new(invalid_value) #=> nil
or
a = Widget.new(invalid_value) #=> raises an exception

Which of these do you prefer and why?

Would you prefer both? How about a 'Widget.new!' method that throws an
exception?

Thanks,
_Kevin
 
T

Timothy Hunter

_Kevin said:
Suppose I've written a class that does something useful.

This class, let's call it a Widget, is created like this...

a = Widget.new(some_value)

Not all values of 'some_value' are valid and I need to indicate when
creation fails.
I see two ways to signify this...

a = Widget.new(invalid_value) #=> nil
or
a = Widget.new(invalid_value) #=> raises an exception

Which of these do you prefer and why?

Would you prefer both? How about a 'Widget.new!' method that throws an
exception?

Thanks,
_Kevin
Exception. It's not really a matter of preference. YourClass.new
allocates an instance of your class and then calls initialize on the new
instance. YourClass.new will return the new instance unless initialize
raises an exception.

Now some advanced Rubyists out there will jump in and explain how to
subvert the allocate/initialize process but you're asking about the
"usual" case, right?
 
R

Robert Klemme

Exception. It's not really a matter of preference. YourClass.new
allocates an instance of your class and then calls initialize on the new
instance. YourClass.new will return the new instance unless initialize
raises an exception.

Fully agree. More arguments in favour of exceptions: what do you do
with your nil instance? You either explicitly check it for nil and -
throw an exception or choose a different path of execution. If you
throw an exception you could have done so in initialize right away. If
you chose another course of execution, well that can be done more
cleanly with begin / rescue / end. If you do not check it you get an
exception anyway when you invoke the first Widget method on nil. This
shows another disadvantage: if you forget to check for nil or store the
instance away and do not directly use it you will be bitten by en
exception much later and the original error is less easy to debug.
Now some advanced Rubyists out there will jump in and explain how to
subvert the allocate/initialize process but you're asking about the
"usual" case, right?

Hehe... I won't disclose the secret. >-}

robert
 
K

_Kevin

Yeah,

This is the approach I have generally taken. If it's not valid, raise
an exception. One can always do something like....

a = Widget.new(invalid) rescue nil

Thanks,
_Kevin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top