ramya2005 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Perl Monks:

1. How to write a function which can accept either a scalar or a hashref as a parameter.
2. How to find out whether the received parameter is a scalar or a hashref
my $code = 'default'; my $hash = {"1"->'ENABLE', "2"->'DISABLE'}; # Call function foo with the scalar my $ret = foo($code); # Call function foo with the hash $ret = foo($hash); sub foo(){ $param = shift; # If $param is a scalar # Do something # Else # Do something }
Thanks
  • Comment on How to Check whether the Function Parameter is a Scalar or a Hashref
  • Download Code

Replies are listed 'Best First'.
Re: How to Check whether the Function Parameter is a Scalar or a Hash
by Skeeve (Parson) on Oct 05, 2005 at 22:26 UTC
    ref is your friend
    SWITCH: for (ref $param) { /HASH/ && do { # Do something for hash ref last SWITCH; }; /^$/ && do { # Do something for scalar last SWITCH; }; }
    You ccan also add whatever else you might need, like:
    /ARRAY/ && do { # Do something for array ref last SWITCH; };

    $\=~s;s*.*;q^|D9JYJ^^qq^\//\\\///^;ex;print

      Be careful about ref $data. If it's blessed, your checks will fail. Whether or not that matters, of course, depends upon the needs of the particular program.

      Cheers,
      Ovid

      New address of my CGI Course.

        If it's blessed, your checks will fail.

        For some not very good definitions of fail...

        Maybe I'm missing your point? The way I see it, if anyone actually needs to heed your warning either they are clever enough to work it out on their own or their design is questionable and should probably be fixed.

        The documented behavior—ref returning the package a blessed ref has been blessed into—seems totally sane to me. If ref still returned "HASH" and you could find yourself in the position of unknowingly violating the documented interface for some thingy, I'd consider that a far worse failure condition; wouldn't you?

        It's true that Perl gives you enough rope to hang yourself with... but shouldn't we warn people about looping that rope around their neck instead of just warning them about an arbitrary foot long section of the rope itself?

        † For some reason, this reminds me of the warning on some blow dryers: "Do not use while showering or bathing."

        -sauoq
        "My two cents aren't worth a dime.";
        

      Another way to explain the same thing (since it took me a minute to parse the above code: I'm sure someone thinks as weirdly as I do!):

      sub href_or_scalar { my $param = shift; my ($is_scalar, $is_hashref) = (0,0); if ( ! ref $param ) { $is_scalar = 1; } elsif ( ref $param eq 'HASH' ) { $is_hashref = 1; } else { die("I only accept a scalar or a HASHref!"); } print STDERR "'$param' is: (scalar => $is_scalar, hashref => $is_h +ashref)\n"; } href_or_scalar( 'hello!'); href_or_scalar( 'HASH' ); href_or_scalar( { key => 'value' } ); href_or_scalar( [ 'key' => 'value' ] ); __END__ 'hello!' is: ( scalar => 1, hashref => 0) 'HASH' is: ( scalar => 1, hashref => 0) 'HASH(0x225490)' is: ( scalar => 0, hashref => 1) I only accept a scalar or a HASHref! at c:\test.pl line 12.
      <-radiant.matrix->
      A collection of thoughts and links from the minds of geeks
      The Code that can be seen is not the true Code
      "In any sufficiently large group of people, most are idiots" - Kaa's Law
      Per Ovid's cautions, it is more robust to use UNIVERSAL::isa than ref if you are looking for a specific base type.

      Caution: Contents may have been coded under pressure.