はじめまして。
現在、業務で他人の書いたコード(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で質問しましょう!
似たような質問が見つかりました
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- JavaScript EasyUIのSubGrid(jquery)におけるObjectに入れた連想配列について 1 2022/05/02 11:21
- Perl perlをバージョンアップしたら、今まで正常に動いていたプログラムが、エラーになってしまった 3 2022/10/05 15:44
- その他(プログラミング・Web制作) Python - Excel で Webからデータを連続取得したいのですが エラーが出ます 1 2023/07/06 20:08
- その他(プログラミング・Web制作) pythonでDBのカラム名で取得したオブジェクトの値を表示したい 1 2022/05/13 03:41
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- その他(プログラミング・Web制作) データ解析ソフトRでのファイル入力read.csvがエラーになります 7 2022/03/27 22:11
- JavaScript 【jquery】EasyUIのSubGridにMySQLのテーブルデータを表示&編集にしたい 5 2022/05/02 13:10
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- Excel(エクセル) 格納したデータを配列のように扱う方法はありますか? 8 2023/06/05 08:53
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ポインター引数の関数でコンパ...
-
stable diffusionのエラー
-
pythonでDBのカラム名で取得し...
-
matlabのソースコードをpython...
-
エクセルVBA:日付データの変換...
-
C言語の構造体にてバブルソート...
-
データの値の近いものをグルー...
-
printfの%eで指数部分の桁数を...
-
テキストファイルの結合について
-
パイソン、データーサイエンス...
-
POSTで配列のデータを渡す方法は?
-
基本クラスのポインタから、特...
-
オセロゲーム 2次元配列で困...
-
花の名前を教えて下さい。
-
途中経過も表示するプログラム
-
python 気象データの取得
-
UTF-8で5~6バイトになる文字コ...
-
COBOLのCOMP形式について
-
ビットスワップとバイトスワッ...
-
エクセルシート名の制限を変更...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ポインター引数の関数でコンパ...
-
stable diffusionのエラー
-
printfの%eで指数部分の桁数を...
-
エクセルVBA:日付データの変換...
-
int型(2バイト)データの分割
-
c言語の多次元配列で1から100ま...
-
C#でのswitch文
-
【Excel VBA】10進数を2進数に...
-
途中経過も表示するプログラム
-
CreateProcessでの環境変数の設...
-
pythonでDBのカラム名で取得し...
-
C言語についてです! 同じ年の...
-
linuxのシェルでファイル名に先...
-
c言語 配列から数字だけをint型...
-
c言語での wavファイルの編集(...
-
matlabのソースコードをpython...
-
ビットデータのチェック方法
-
10個の実数に対する降順ソート...
-
python 気象データの取得
-
C言語の構造体にてバブルソート...
おすすめ情報