はじめまして。
現在、業務で他人の書いたコード(Perl)を改造しているのですが、その作成者がいなくなってしまっております。
そのコードを見ると、なぜ、このような書き方が可能なのか、理解できないので、動作原理を教えていただけないでしょうか?
以下のようなコードです。
====================================
my @arr = ( "一" , "ニ" , "三" , "四" ) ;
my %data ;
$data->{0} = \@arr ;
$data{0}{test} = "テスト" ;
print ${$data->{0}}[1] . "\n" ;
print $data{0}{test} . "\n" ;
====================================
出力はこのようになります。
ニ
テスト
ここからが質問なのですが、$data->{0}という書き方ができる理由が分からないのです。
$dataが例えば、
my %my_hash ;
my $data = \%my_hash ;
というように、ハッシュのリファレンスであるならば、$data->{0}という書き方も分かるのですが、定義した時点でリファレンスではない、$dataに、何故"->"の演算子が使えるのでしょうか?
とはいえ、
ref $data ;
の戻り値がHASHとなるのも確認しています。
これもどうしてそうなるのか、根本的な原理が分かっておりません。
どうか、このコードの動作原理を教えていただけないでしょうか。
抽象的な質問となっている気がしますが、宜しくお願いいたします。
No.1ベストアンサー
- 回答日時:
自動的に作成されるからです。
Perl の場合、「未定義の変数にはすべて undef が代入ずみ」という仮定になっています。
よって、宣言していない $data という変数にも、いきなりアクセスできてしまうのです。
$data->{0} という記述をすると、Perl は自動的にハッシュのリファレンスを構築します。
理論上は、10次元配列とかでも宣言なしでアクセス可能です。
この回答への補足
大変申し訳ありません。
もう1つ分かっていない点があることが分かりましたので、補足させてください。
まず、
my %data ;
これについては、特別意味がないわけですよね。
その後、突然、
$data->{0}
という記述が出るため、Perlが、$dataは、
「ハッシュのリファレンスである」
と判断し、作成をするわけですね。
となると、その後で、$data{0}
という書き方が可能なのは何故なのでしょうか?
ハッシュのリファレンスにキーをつけて参照や書き込みをするならば、
$data{0}
ではなく、
${$data}{0}
となるような気がするのですが・・・。
もしよろしければ教えてください。
ご回答ありがとうございます。
自動的に作成されるということで、
my %data ;
の宣言文をコメントアウトしても、全く同様に動くことが確認できました。
つまり、%dataという実ハッシュ宣言自体は、今回のケースにおいては意味を持たないということですね。
大変分かりやすい回答ありがとうございました。
No.2
- 回答日時:
どうやら基本的な部分で誤解されているようなので、補足します。
perl では、$data と %data は全く別の変数を表します。
(ついでに @data も上記の2つとは別変数)
ですから、ご質問のプログラム内の
$data->{0} と $data{0}{test} は別の変数になります。
$data{0}{test} は、2行目で定義されている連想配列を
参照しており、
$data->{0} は、宣言なしでいきなり使用された変数($data)を参照していることになります。
では、2行目に全く意味がないのかというとそうでもなく、
my で宣言していることから変数のスコープ(ローカル変数とかグローバル変数とか)を定義していると考えられます。
回答ありがとうございます。
本当に根本的な部分で誤解をしていました。
$data, %dataが同時利用可能であることは知りませんでした。
(他の言語でもありうるのでしょうか?)
だとすると、my宣言の意味も分かります。
(質問文に記載したコードでは意味が薄いかもしれませんが・・・)
これで全て分かりました。
皆様本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C++/CLIのオブジェクト型配列
-
2バイトの文字データの送信
-
途中経過も表示するプログラム
-
ポインター引数の関数でコンパ...
-
エクセルVBA:日付データの変換...
-
stable diffusionのエラー
-
c言語 Bitについて
-
pythonでDBのカラム名で取得し...
-
ビットデータのチェック方法
-
printfの%eで指数部分の桁数を...
-
エクセルシート名の制限を変更...
-
UTF-8で5~6バイトになる文字コ...
-
Excel 1セル当りの文字数が2...
-
10Mバイトて文字数に すると何...
-
DOSのdirコマンドで思うように...
-
EUSARTで通信
-
Excel VBA メール作成について ...
-
VBSでテキストファイルの文字列...
-
DataGridViewの特定列に入力さ...
-
[VBScript][wsh]byte単位でのデ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ポインター引数の関数でコンパ...
-
stable diffusionのエラー
-
printfの%eで指数部分の桁数を...
-
エクセルVBA:日付データの変換...
-
int型(2バイト)データの分割
-
【Excel VBA】10進数を2進数に...
-
C#でのswitch文
-
C言語についてです! 同じ年の...
-
pythonでDBのカラム名で取得し...
-
PINVOKEで構造体配列をマーシャ...
-
MySQLに登録すると文字化け
-
C言語 ファイル内のデータと入...
-
CreateProcessでの環境変数の設...
-
'dataType' 引数を Null にする...
-
linuxのシェルでファイル名に先...
-
Cのプログラムがどうしても動き...
-
POSTで配列のデータを渡す方法は?
-
マクロ登録したピボットが重い...
-
gnuplotの出力グラフ名を外部で...
-
離散フーリエ変換のプログラム...
おすすめ情報