Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^5: chaining method calls (perl/DWIM)

by tye (Cardinal)
on Jun 20, 2003 at 05:37 UTC ( #267464=note: print w/ replies, xml ) Need Help??


in reply to Re^4: chaining method calls (perl/DWIM)
in thread chaining method calls

How often have you written code like

$ref = { foo => open( BAR, "> baz" ), bar => print( BAR "biff\n" ), };
the above? If you do, then, yes, you write bizarre enough code that my DWIM design will likely not do what you mean.

This part of the design is only for methods that don't return interesting values, merely success/failure notification (though in the form of an object to enable chaining of methods). So if you are in the habit of squirreling away uninteresting values in long-lived locations that you never check, then, yes, you won't know about failures until global destruction. But then, if you do that and don't have my error object, then you won't know about failures period, so I fail to see the problem. Yes, if I always threw exceptions you could argue that one would know about failures no matter what, but I think you'd find many people would just get very sloppy about catching and ignoring way too many exceptions and you really wouldn't be in that much of a better position.

I can see some value in "all failures are exceptions", but I really do think it goes too far. Sometimes the failure cases are the reason for the flow and so should be handled as part of the flow, not forced into some exception catcher. Why just this week I was forced to catch some exceptions that really should have been normal failures and it was much more painful that way.

                - tye


Comment on Re^5: chaining method calls (perl/DWIM)
Download Code
Re^6: chaining method calls (perl/DWIM)
by adrianh (Chancellor) on Jun 20, 2003 at 16:36 UTC

    I don't think code like:

    package Foo::Live; sub new { my $class = shift; return bless { iterator => Iterator->new(class => $class)->where(live => 1); }, class; }; sub next { my $self = shift; $self->{iterator}->next; };

    is particularly bizarre (if you accept the chained method idiom). Yet I wouldn't expect:

    my $foo = Foo::Live->new; while (my $subfoo = $foo->next) { print "$subfoo\n" };

    to fail silently if where returned an error object. These are the sort of, I think, legitimate uses that could cause unexpected results. YMMV

    This part of the design is only for methods that don't return interesting values, merely success/failure notification (though in the form of an object to enable chaining of methods). So if you are in the habit of squirreling away uninteresting values in long-lived locations that you never check, then, yes, you won't know about failures until global destruction.

    When I use the method-chaining idiom I am often interested in the last value. Perhaps this is an argument against method chaining ;-)

    But then, if you do that and don't have my error object, then you won't know about failures period, so I fail to see the problem.

    Depends. In the cases where you are using method chaining you get an error as soon as you try and treat it as an object.

    Yes, if I always threw exceptions you could argue that one would know about failures no matter what,

    You knew what I was going to say didn't you :-)

    but I think you'd find many people would just get very sloppy about catching and ignoring way too many exceptions and you really wouldn't be in that much of a better position.

    I guess part of it is that I like to have a uniform error handling mechanism across a project. My mental facilities are too meagre to spend time considering whether a normal return value, an error object or an exception is more appropriate. So I just throw an exception. In my personal experience this helps more than it hinders.

    I can see some value in "all failures are exceptions", but I really do think it goes too far. Sometimes the failure cases are the reason for the flow and so should be handled as part of the flow, not forced into some exception catcher. Why just this week I was forced to catch some exceptions that really should have been normal failures and it was much more painful that way.

    I just never find it that much hassle. I still code so that success is indiciated by a true return value. That way you can always write:

    $o->foo unless eval { $foo->bar };

    avoiding nasties like

    eval { $foo->bar }; $o->foo if $@;

    When the exception is the driver for the mainline.

    Anyway - I think this is probably a to-may-to/to-mah-to issue so I'll shutup and stop being annoying :-)

      If the last method in the chain returns an interesting value, then that method wouldn't return an error object on failure.

      I guess even if you need to return false values, you can still do

      if( ! eval { $count = $obj->GetCount(); 1 } ) { # Can determine count }
      so Perl makes it pretty easy to turn exceptions into Booleans. My real-life "more painful" example was in C++ (I don't see many thrown exceptions in Perl).

      But every time I start down the road of throwing exceptions in Perl, I run into a lack of standardization and don't manage to pick an exception module to use. So I don't have a good excuse.

                      - tye

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2014-09-22 06:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (182 votes), past polls