Patterns::UndefObject

A version of the undefined object (null object) pattern
Download

Patterns::UndefObject Ranking & Summary

Advertisement

  • Rating:
  • License:
  • Perl Artistic License
  • Price:
  • FREE
  • Publisher Name:
  • John Napiorkowski
  • Publisher web site:
  • http://search.cpan.org/~jjnapiork/

Patterns::UndefObject Tags


Patterns::UndefObject Description

Patterns::UndefObject is a version of the undefined object (null object) pattern.Sometimes when you are calling methods on a object you can't be sure that a particular call chain is going to be valid. For example, if you are using something like DBIx::Class you might start by finding out if a given user exists in a database and then following that user's relationships for a given purpose: my $primary = $schema ->resultset('User') ->find(100) ->telephone_numbers ->primary;However this call chain will die hard during dynamic invocation should the method call find(100) fail to find a user. This failure would return a value of undef and then a subsequent "Can't call method 'telephone_numbers' on an undefined value.This often leads to writing a lot of defensive code: my $primary; if(my $user = $schema->resultset('User')) { $primary = $user ->telephone_numbers ->primary; } else { $primary = "Unknown Number"; }Of course, to be truly safe, you'll need to write defensive code all the way down the chain should the relationships not be required ones.I believe this kind of boilerplate defensive code is time consuming and distracting to the reader. Its verbosity draws one's attention away from the prime purpose of the code. Additionally, it feels like a bit of a code smell for good object oriented design. Patterns::UndefObject offers one possible approach to addressing this issue. This class defined a factory method called "maybe" which accepts one argument and returns that argument if it is defined. Otherwise, it returns an instance of Patterns::UndefObject, which defines AUTOLOAD such that no matter what method is called, it always returns itself. This allows you to call any arbitrary length of method chains of that initial object without causing an exception to stop your code.This object overloads boolean context such that when evaluated as a bool, it always returns false. If you try to evaluate it in any other way, you will get an exception. This allows you to replace the above code sample with the following: use Patterns::UndefObject; my $primary = Patterns::UndefObject ->maybe($schema->resultset('User')->find(100)) ->telephone_numbers ->primary || 'Unknown Number';You can use the available export Maybe to make this a bit more concise ( particularly if you need to use it several times). use Patterns::UndefObject 'Maybe'; my $primary = Maybe($schema->resultset('User')->find(100)) ->telephone_numbers ->primary || 'Unknown Number';Personally I find this pattern leads to more concise and readable code and it also provokes deeper though about ways one can use similar techniques to better encapsulate certain types of presentation logic.SYNOPSIS use Patterns::UndefObject 'Maybe'; my $name = Maybe($user_rs->find(100))->name || 'Unknown Username';Product's homepage


Patterns::UndefObject Related Software