how to create a subroutine that accepts all types of variable(scalar, hash, array or ref)

StackOverflow https://stackoverflow.com/questions/21746806

  •  10-10-2022
  •  | 
  •  

Question

How to create a subroutine that accepts all types of variable and determine if it's (scalar, hash, array or ref)

sub know_var {
    my $this_var = shift;

    if ($this_var eq "array"){
        print "This variable is an array!";
    } elsif ($this_var eq "hash") {
        print "This variable is a hash!";
    } elsif ($this_var eq "hash ref") {
        print "This variable is an hash reference!";
    } so on..

}

my @array = ('foor', 'bar');
my %hash  = (1 => "one", 2 => "two");
my $scalar = 1;
my $scalar_ref = \$scalar;
my $hash_ref = \%hash;
my $arr_ref = \@array;

know_var(@array);
know_var($scalar_ref);
and so on...

My goal for this is I want to create a subroutine that is similar to Data::Dumper, and my first problem is to determine what kind of variable am going to deal with.

Était-ce utile?

La solution

From perlsub

The Perl model for function call and return values is simple: all functions are passed as parameters one single flat list of scalars, and all functions likewise return to their caller one single flat list of scalars. Any arrays or hashes in these call and return lists will collapse, losing their identities--but you may always use pass-by-reference instead to avoid this.

So, you can use references and ref() to check type of reference

sub know_var {
  my $this_var = shift;

  if (ref($this_var) eq "ARRAY") { 
    print "This variable is an array reference!";
  }
  elsif (ref($this_var) eq "HASH") { 
    print "This variable is an hash reference!";
  }
  elsif (ref($this_var) eq "SCALAR") { 
    print "This variable is an scalar reference!";
  }
  elsif (!ref($this_var)) { 
    print "This variable is plain scalar!";
  }

}

know_var(\@array);
know_var(\%hash);
know_var(\$scalar);
know_var($scalar);

Autres conseils

In the spirit of TIMTOWTDI, and in the interests of pimping my own wares, here's an alternative, using multisubs...

use v5.14;
use warnings;
use Kavorka qw( multi fun );

multi fun foobar (ArrayRef $x) {
   say "It's an array";
}

multi fun foobar (HashRef $x) {
   say "It's a hash";
}

multi fun foobar (Num $x) {
   say "It's a number: $x";
}

multi fun foobar (Str $x) {
   say "It's a string: $x";
}

foobar( [] );
foobar( {} );
foobar( 1.234 );
foobar( "Hello world" );
foobar( \*STDOUT );  # dies
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top