in reply to Better way to dereference a shifted hashref arg?

Update I fixed my original proposal with a comma kluge (so that it wouldn't die when the input was a ref to an empty hash. The resulting line is so long and tortured that it hardly qualifies as a one-liner, and it is not particularly clear coding, so I don't think it is worth the trouble. FWIW, here it is (along with some minimal testing code):

use strict; use warnings; use Scalar::Util 'reftype'; use Test::More 'no_plan'; sub foo { reftype( $_[ 0 ] ) || '' eq 'HASH' and ( my %h = %{ shift() } ), 1 o +r die; return 1; } ok( eval { foo(+{}) }, 'empty hashref' ); ok( !eval { foo() }, 'no input' ); ok( !eval { foo( 1 ) }, 'bad input: constant' ); ok( !eval { foo( [] ) }, 'bad input: array ref' ); ok( eval { foo( +{ 1 => 1 }) }, 'good input' ); __END__

Update #2771: Changed the code to use Scalar::Util::reftype instead of UNIVERSAL::isa, in response to chromatic's comment. If the code was tortured before, it is even more so now. The business with || '' is to silence a warning.

the lowliest monk

Replies are listed 'Best First'.
Re^2: Better way to dereference a shifted hashref arg?
by chromatic (Archbishop) on Jun 15, 2005 at 17:36 UTC

    This code is almost always wrong:

    UNIVERSAL::isa( $_[ 0 ], 'HASH' )

    Besides breaking polymorphism, it's unreliable:

    my $x = bless \(my $y), 'HASH';

    Use Scalar::Util's reftype() instead.

      Thanks++ for the pointer. Interestingly, a few months ago I would have used ref $_[ 0 ] eq 'HASH', but I switched to using UNIVERSAL::isa upon reading the advice of some high-ranking monk (can't remember who, though), who deprecated such use of ref because it failed on blessed references.

      My point is that sometimes best practices in Perl seem to be a moving target.

      More than once I have seen convincing arguments for why stuff that appears in the Perl docs is actually bad programming (e.g. using AUTOLOAD for defining accessors; making constructors dual class/object methods; using INIT for initialization code). I realize that this is in part due to the fact that the docs are contributed by users, who may not know any better, and also because Perl is a "work in progress," but I wonder how Perl compares in this regard with other languages, and whether this uncertainty on best practices deters people from choosing Perl as a language for development.

      Maybe TheDamian's upcoming best practices book will put a stop to that, or at least slow down the mutation rate for best practices.

      the lowliest monk