How to tell if variable is Array, Hash, or Scalar?

Hi,

I want to write a function to manipulate the variable that's passed into it, but if it's an array or hash i want to do the change to each member.  is there an easy way to tell what type a variable is in Perl without making it a reference ?

example function:

sub manipulate($) {
  my $var = shift;
  if ($var is an array) {
    foreach my $v (@var) {
      ...
    }
  }
  elsif ($var is a hash) {
    ...
  }
  return $var;
}
KnotEyeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ozoCommented:
if( ref $var eq 'ARRAY' ){
    foreach my $v ( @$var ){
    }
}elsif( ref $var eq 'HASH' ){
}
jmcgOwnerCommented:
By declaring the function as taking only a scalar as its argument, you've limited what Perl will allow the function to be called with to simple scalars and references. You can use the 'ref' operator (as Ozo has shown) to distinguish between the two cases and, further, can use it to distinguish between references to various types.

From the language you used to describe what you wanted to do, however, I'm not sure this is what you wanted.

Ordinary functions, where you haven't predeclared the type of their argument list, treat the arguments as a _list_. If you call one of these functions with an array or hash, the elements of the array or hash are added to the list and any original boundaries between arrrays or hashes are lost (unless you've supplied other arguments that allow them to be reconstructed). One thing you'd be able to do with the passed-in list is determine how many elements are in the @_ array. You could make a decision based on whether the count was 0, 1, or more-than-one.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
KnotEyeAuthor Commented:
i think you're right, jmcq.  they do get flattened when passing them in, so i am going to have to use references, or parse the list on input. i think references will work better.  a better example of what i want to do is, say, auto-increment every element that gets passed in, whether it's all the values of a hash, array, or scalar:

@values = inc(@values);
%vals = inc(%vals);
$value = inc($value);

all with the same function.  any ideas, or am i stuck with references ?
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

ozoCommented:
Well, if you want to increment keys as well as values, you could do someting like
use Data::Dumper;
sub inc{
    $_++ for @_;
    return @_[0..$#_];
}
@values = (1,2,3);
%vals=(
aa=>'bb',
cc=>'dd',
);
$value = 5;
@values = inc(@values);
%vals = inc(%vals);
$value = inc($value);
print Dumper \@values;
print Dumper \%vals;
print Dumper \$value;

otherwise you might be stuck with
sub incref{
    for( @_ ){
        if( ref eq 'ARRAY' ){
           $_++ for @$_;
        }elsif( ref eq 'HASH' ){
           $_++ for values %{$_};
        }elsif( ref eq 'SCALAR' ){
            $$_++;
        }elsif( !ref ){
            $_++;
        }
    }
}

incref(\@values);
print Dumper \@values;
incref(\%vals);
print Dumper \%vals;
incref(\$value);
print Dumper \$value;
incref($value);
print Dumper \$value;
jmcgOwnerCommented:
Based on the example you bring up, I think you'll need to start looking at the _object oriented_ aspects of Perl. This 'inc' idea becomes complicated once you start having to answer questions like the ones Ozo has already asked: "did you mean to increment the _keys_ as well as the _values_ of the hash?"
KnotEyeAuthor Commented:
thanks guys, you've both been helpful.  i'll split the points between you
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Perl

From novice to tech pro — start learning today.