Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re(6): Null objects in boolean context

by Ovid (Cardinal)
on Jan 01, 2004 at 22:10 UTC ( [id://318170]=note: print w/replies, xml ) Need Help??


in reply to Re: Re: Re: Re: Re: Autoboxing: Yes or No?
in thread Autoboxing: Yes or No?

mirod wrote: If I use a Null Object I cannot write if( $elt->first_child) {...} anymore.

Ovid begs to differ :)

package Null::Object; use overload 'bool' => \&bool; my $self; sub new { $self ||= bless {}, shift } sub AUTOLOAD { $self } sub bool { return; } package main; my $null = Null::Object->new; $null->foo->bar->baz; if ($null) { print "We shouldn't be here!"; } else { print "We are false!"; }

That might need a bit of tuning, but you get the idea.

Update: I just noticed that you mentioned overload, so my bit of code is not news to you :) On the other hand, if clean null objects is the only benefit of autoboxing, then I again can't see much of a benefit to them. I might also add that null objects should be the exception rather than the rule, thus the performance impact should be minimal (I hope).

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re: Re(6): Null objects in boolean context
by rkg (Hermit) on Jan 01, 2004 at 22:57 UTC
    Ovid this is very interesting... can you explain when you would use this? I've been reading the refactoring book, and like the idea of null objects, but I cannot wrap my brain around your post. Would you put this in the inheritance tree of all objects? Where would one put in the correct behavior for say a Null DBI connection or a Null EmployeeAddress or whatever?

    Thanks for clarifying this for me and all --

    rkg

      The fact that you ask the question indicates that you are too inclined to use inheritance.

      Null objects exist. They make perfect sense on their own. They are an appropriate thing to return when you want to fail to produce a useful object, but do it silently in a chained set of method calls. Just return a Null and let the caller deal with it.

      Think of NULL in a database. It represents missing data. It can appear when you expected any other data type. There aren't (well, except in some vendor extensions) different kinds of NULLs. There don't have to be.

      What are your alternatives? What could have been a simple chain of method calls followed by one if now has to turn into a nested set of if's as you test every method call for success to know if you can make the next. Or you have to wrap it in an eval and complicate your error handling needlessly. The Null is clean, simple, understandable, and that is all that is needed to justify Null's existence.

      No. I would have null objects inherit from something like this (though I might not want the singleton). Because it automatically generates methods, you don't want those created for a real object. However, for a null object, it might be appropriate. For example, let's say that you have a customer and you want to get the sum total of all of his or her orders. Internally, the Customer class might have a method like this:

      sub total_all_orders { my $self = shift; my $total = 0; $total += $order->total foreach $self->orders; return $total; }

      In this case, what if some of those orders are null objects (perhaps this is a design decision that was implemented for cancelled orders), then you could have your Null::Order object:

      package Null::Order; use base 'Null::Object'; sub total { 0 } 1;

      In this case, the null order knows that its total value is zero (this example doesn't make as much sense for Perl because the false value will be converted to zero, but it's perfect for other languages).

      Or you could have a null customer object get returned that has generic information for customers not in your mailing list database and automatically ignores the $customer->add_purchase; method rather than adding it to the database.

      Cheers,
      Ovid

      New address of my CGI Course.

Re: Re(6): Null objects in boolean context
by mirod (Canon) on Jan 02, 2004 at 01:41 UTC
    I might also add that null objects should be the exception rather than the rule, thus the performance impact should be minimal (I hope).

    I haven't benchmarked overloading in a while, but as far as I remember, just using it caused quite a huge performance hit in the rest of the code. IIRC something like 30% slower, with 5.6.0. Things might have changed since then though.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (7)
As of 2024-04-23 19:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found