Actually, the nearly-equivalent code is:
sub _get_self {
my $reftype = Scalar::Util::reftype( $_[0] );
$reftype = '' unless defined $reftype;
if ( $reftype eq 'ARRAY' ) {
return tied( @{ $_[0] } || $_[0]
}
return $_[0];
}
(Your version misses the fact that 'ARRAY' is a legal classname and that the value returned from tied() is a blessed hashref which makes the _get_self() for DBM::Deep::Hash more complex.)
(Yes, my code could be shortened if I was able to use // for defined-or. That's a 5.10ism and DBM::Deep runs on practically every Perl version since 5.004, we think.)
I don't like that code for three reasons:
- It's 6 times longer and has at least twice the number of codepoints. This makes it at least 4 times harder to comprehend at a glance.
- Writing that code correctly to function in all cases is hard. I had to edit my version twice as I was writing this reply because I found edge cases.
- It assumes that $_[0] will never be something that wants to pretend it's an array using overload. For example, using Contextual::Return or some other magic.
By using an eval-block, you allow the item to behave the way it wants to behave, if it wants to behave that way, plus you let Perl worry about the edgecases. To get truly equivalent code would be about 40 lines and I don't think I could get it all correct. At that point, an eval-block is quicker.
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
|