Beefy Boxes and Bandwidth Generously Provided by pair Networks kudra
Perl Monk, Perl Meditation
 
PerlMonks  

Re^2: Moose: return null object

by halfcountplus (Hermit)
on Apr 18, 2011 at 15:40 UTC ( #899964=note: print w/ replies, xml ) Need Help??


in reply to Re: Moose: return null object
in thread Moose: return null object

As long as the class...returns something for failure

Well, obviously there is no choice about that, lol. No matter what, it is going to return a hash ref.

I'd rather just set an "ok" Bool attribute in BUILD than use eval. It is not that I'm worried about invalid args (strings for ints, or whatever), it's to do with otherwise valid args in cases where the object cannot be created because of a program logic constraint.

So all that's fine, just it seems (very) silly (as in: pointlessly silly, silly oversight kind of silly) that you cannot return undef from a "new" call, and thot perhaps I'd missed something. But I'm not here to pick on Moose either ;)


Comment on Re^2: Moose: return null object
Re^3: Moose: return null object
by stvn (Monsignor) on Apr 19, 2011 at 02:10 UTC
    So all that's fine, just it seems (very) silly (as in: pointlessly silly, silly oversight kind of silly) that you cannot return undef from a "new" call, and thot perhaps I'd missed something. But I'm not here to pick on Moose either ;)

    Well, basically it is not an oversight at all, it is *very* deliberate. This is basically a variant of the "return value" vs. "exception" debate which happens any time you lock a C programmer and Java programmer together in a room for a long enough period of time. We (myself and the other core Moose devs) believe that exceptions are the way to go, so therefore Moose reflects this opinion. But it also goes a little deeper then that, to the philosophy of what is a "Class".

    In non-Moose Perl OO, new was simply a method that you could make do whatever you wanted, convention said it was the method that constructed a new instance, but that was simply just convention. There was nothing special about new either, in fact it was a common idiom for a while to do $instance->new as a sort of cloning technique. But in the end, a "Class" in non-Moose Perl OO is not really a rigorously defined concept, but instead really just a loose set of conventions accumulated over time and borrowed from other languages. Now, there is nothing at all wrong with this, it is very powerful and extremely flexible, however it also suffers from the common "dark-side" of TIMTOWTDI.

    In contrast, Moose defines "Class" much more rigorously, in particular it thinks that one of the primary functions of a "Class" is as an instance construction factory. So much so that new in Moose will eventually call $class->meta->new_object to get the instance (delegating up to the Class meta-object). So keeping with this philosophy, new should *always* return an instance, and if it cannot for whatever reason return an instance, it should explode loudly with an exception.

    -stvn
      Thank you for the information. I have asked myself the same question as the original poster. Probably because I also write in Java and a null object is pretty common there. This should certainly go into the Moose FAQ.
        Probably because I also write in Java and a null object is pretty common there

        It is, but you will never see one returned from a constructor.

        -stvn

      If you, as core developer, believe that "exceptions are the way to go", why does Moose produce such horrible, unhelpful, Java-style backtraces when dieing? For example when a type constraint is violated, I get about 7 lines of output that contribute nothing to the error cause, and have to combine the first and the last line to make up something that might actually relate to the error at hand:

      Q:\>perl -MMoose -e "package Moo;use Moose; has 'foo' => (is => 'ro', +isa => 'Int'); no Moose; package main; my $bar = Moo->new({foo => 'bo +om'});" Attribute (foo) does not pass the type constraint because: Validation +failed for 'Int' failed with value boom at g:/Systeme/tools/pe rl-5.10.0/perl/site/lib/Moose/Meta/Attribute.pm line 774 Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Attri +bute=HASH(0x190c5f4)', 'boom', 'Moo=HASH(0x190c934)') called a t g:/Systeme/tools/perl-5.10.0/perl/site/lib/Moose/Meta/Attribute.pm l +ine 428 Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta: +:Attribute=HASH(0x190c5f4)', 'Moose::Meta::Instance=HASH(0x187 145c)', 'Moo=HASH(0x190c934)', 'HASH(0x3ea354)') called at g:/Systeme/ +tools/perl-5.10.0/perl/site/lib/Class/MOP/Class.pm line 365 Class::MOP::Class::_construct_instance('Moose::Meta::Class=HAS +H(0x187104c)', 'HASH(0x3ea354)') called at g:/Systeme/tools/pe rl-5.10.0/perl/site/lib/Class/MOP/Class.pm line 352 Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x18710 +4c)', 'HASH(0x3ea354)') called at g:/Systeme/tools/perl-5.10.0 /perl/site/lib/Moose/Meta/Class.pm line 205 Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x1871 +04c)', 'HASH(0x3ea354)') called at g:/Systeme/tools/perl-5.10. 0/perl/site/lib/Moose/Object.pm line 25 Moose::Object::new('Moo', 'HASH(0x12ca3ec)') called at -e line + 1

      If you think something is a good engineering practice when using your tool, wouldn't it be a good idea to design your tool in a way that your tool encourages the practice instead of hindering it? Sending the programmer on a merry chase along exception paths is not friendly to the programmer.

      If you use one of the standard exception mechanisms, like for example Carp, judicious use of @CARP_NOT can slim down the backtrace tree easily. Also, either passing down the (top-level) error cause to the place where the error gets detected will improve the feedback instead of requiring the programmer to intuit the error cause from the message(s) they get.

        There seems to be no consensus on stack traces. Personally I find them very useful, you obviously differ in that opinion but still do see some usefulness, while others think they are simply evil incarnate.

        To be honest, I wanted originally to use exception objects, but so many people/tools/programs expect die to throw a string and so many existing exception-object modules jumped through so many hoops it just turned me off from the idea. That said, these days I use Throwable and love it.

        If you use one of the standard exception mechanisms, like for example Carp, judicious use of @CARP_NOT can slim down the backtrace tree easily

        Moose does use Carp actually.

        I will the first to admit (and I suspect many of the other core devs would agree) that Moose could use some better errors. There are few modules out there that couldn't use some help with errors, it is all too common to leave them till the end. Any help you would like to provide, I am sure would be greatly appreciated.

        -stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://899964]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2014-04-19 18:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (483 votes), past polls