- ベストアンサー
変数名を配列として利用するには?
複数のモジュールに記述されている配列を1つの配列へ代入したいと思っています。 単純に考えれば、 @array = (@Module1::array, @Module2::array, @Module3::array); で良いのですが、モジュールが多岐に渡っており、モジュール名自体はスカラー変数へ代入して置き、それを利用したいと考えています。 @array = (); foreach $m (qw(Module1 Module2 Module3)) { $mn = $m. '::array'; foreach $w (@{$mn}) { # @Module1::array にアクセスしているつもり push(@array, $w); } } この様なイメージです。 しかし、@{$mn}は Can't use string ("変数名") as an ARRAY ref while "strict refs" in use at 行番号. になってしまいます。 スカラー文字列に入っている配列変数へアクセスするにはどう記述すれば良いでしょうか?
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
テストしていないので自信はないのですが、配列名を文字列として組み立てて eval するとうまくいくのではないかと思います。 > foreach $w (@{$mn}) { # この行を、下のように変更する foreach $w (eval('@' . $mn)) {
その他の回答 (1)
- Tacosan
- ベストアンサー率23% (3656/15482)
一応 2通りほど考えてみました: 1. あっさりあきらめてその部分だけ no strict; する 2. パッケージのシンボルテーブルを使って大技で: パッケージ Module1 のシンボルテーブルは $::{'Module1::'} で参照できます. この中から配列 array のデータを取り出せばよいので, @Module1::array は @{$::{'Module1::'}{array}} によっても参照できます. ということで foreach $m (qw(Module1 Module2 Module3)) { push @array, @{$::{$m . '::'}{array}}; } でよいのではないかと. ちなみに配列全体をまとめて push できます.
お礼
Tacosan さん > 1. あっさりあきらめてその部分だけ no strict; する 一瞬諦めかけました(^^;) > 2. パッケージのシンボルテーブルを使って大技で: > パッケージ Module1 のシンボルテーブルは $::{'Module1::'} で参照できます. この中から配列 array のデータを取り出せばよいので, > @Module1::array は @{$::{'Module1::'}{array}} によっても参照できます. あぁ~ なるほど!確かにその通りですね。そこまで気が回りませんでした。 ありがとうございました。
お礼
kumoz さん 素直にevalで囲ってしまう。と言う手もありますね。 コードも分かりやすいし、保守性を確保する上でも良い方法ですね! この方法を採用させて頂きたいと思います。 ありがとうございました。