I'm new to Perl and I understand you can call functions by name, like this: &$functionName();. However, I'd like to use an array by name. Is this possible?

Long code:

sub print_species_names {
    my $species = shift(@_);
    my @cats = ("Jeffry", "Owen");
    my @dogs = ("Duke", "Lassie");

    switch ($species) {
        case "cats" {
            foreach (@cats) {
                print $_ . "\n";
            }
        }
        case "dogs" {
            foreach (@dogs) {
                print $_ . "\n";
            }
        }
    }
}

Seeking shorter code similar to this:

sub print_species_names {
    my $species = shift(@_);
    my @cats = ("Jeffry", "Owen");
    my @dogs = ("Duke", "Lassie");

    foreach (@<$species>) {
        print $_ . "\n";
    }
}
有帮助吗?

解决方案

Possible? Yes. Recommended? No. In general, using symbolic references is bad practice. Instead, use a hash to hold your arrays. That way you can look them up by name:

sub print_species_names {
    my $species = shift;
    my %animals = (
        cats => [qw(Jeffry Owen)],
        dogs => [qw(Duke Lassie)],
    );
    if (my $array = $animals{$species}) {
        print "$_\n" for @$array
    }
    else {
        die "species '$species' not found"
    }
}

If you want to reduce that even more, you could replace the if/else block with:

    print "$_\n" for @{ $animals{$species}
        or die "species $species not found" };

其他提示

You can achieve something close by using a hash of array references:

%hash = ( 'cats' => [ "Jeffry", "Owen"],
          'dogs' => [ "Duke", "Lassie" ] );

$arrayRef = $hash{cats};

You could also use eval here:

foreach (eval("@$species")) {
        print $_ . "\n";
    }

I should have made it clear that you need to turn off strict refs for this to work. So surrounding the code with use "nostrict" and use "strict" works.

This is whats known as a soft reference in perl.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top