Perlでは、名前を使って配列を参照できますか?

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?

ロングコード:

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

このような短いコードを求めている:

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

    foreach (@<$species>) {
        print $_ . "\n";
    }
}
1
追加された 著者 Michael Carman,
perldoc perlreftut を読んで、データ構造を作成するためのより良い方法を説明するかもしれません。すでに投稿されている回答に見られる
追加された 著者 Joel Berger,
すべてが perldoc perlref に明示されています - "シンボリックリファレンス"
追加された 著者 evil otto,

3 答え

可能?はい。お勧めですか? いいえ一般に、シンボリックリファレンスを使用するのは悪い習慣です。代わりに、配列を保持するためにハッシュを使用します。あなたは名前でそれらを見ることができます:

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/elseブロックを次のように置き換えることができます。

    print "$_\n" for @{ $animals{$species}
        or die "species $species not found" };
15
追加された
ああ、シンボリックな参照を使うのはそれほど悪くはない... ... perlでのメタプログラミングが可能になる。
追加された 著者 ennuikiller,

配列参照のハッシュを使用すると、近いものを実現できます。

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

$arrayRef = $hash{cats};
4
追加された

ここでevalを使うこともできます:

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

私は、あなたがこれが働くために厳密な基準を解除する必要があることを明確にしておくべきでした。だから "nostrict"を使用してコードを囲み、 "strict"を使用します。

これはperlでのソフトリファレンスとして知られています。

0
追加された
\ @ $種を意味するかもしれませんが、 \種別このような場合は、 eval という文字列を使用しないことをおすすめします。少なくとも、エラーがないかどうかチェックしてください。
追加された 著者 Eric Strom,
strict はここで重要なエラーを検出しています。 strictをオフにすると、次の変換が行われます: "@ $種" - > "@main :: dogs" - > "' - > eval(' ') - >' '変数がレキシカルなので、OPが望んでいることを静かに実行しません。 OPがパッケージ変数に切り替えられた場合、事態はさらに悪化します。 "@ $種" - > "@main :: dogs" - > "Duke Lassie" - > eval( 'Duke Lassie') - > Lassie-> Duke()を呼び出して、 。私が最初のコメントで言ったように、あなたはおそらく働いていた eval('@'$$ species)がほしいと思っていましたが、これはなぜあなたがしてはいけないのかを強調しています。
追加された 著者 Eric Strom,
あなたは明らかにこれが働くために厳格にする必要があります....
追加された 著者 ennuikiller,
面白いことに、私はこれをテストして、それは完璧に働いた!!
追加された 著者 ennuikiller,
@ code {foreach(@ $種)){...} を使用すると、厳密に無効にした場合、@ code {eval} eval をバイパスします。
追加された 著者 Ven'Tatsu,