Question

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";
    }
}
Was it helpful?

Solution

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" };

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top