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
  •  | 
  •  

Вопрос

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.

Это было полезно?

Решение

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);

Другие советы

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top