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

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

_Kevin wrote:

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?

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

···

On 06.10.2006 14:50, Timothy Hunter wrote:

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

···

On Oct 6, 8:55 am, Robert Klemme <shortcut...@googlemail.com> wrote:

On 06.10.2006 14:50, Timothy Hunter wrote:

> 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