プロが教えるわが家の防犯対策術!

初めまして、自分でhpを持ちたく、Perlの勉強をしておりますパールマンと申します。

連想配列の連想配列で、下記のような

$nihon = {
     'tokyo' => {
           'setagaya' => 1,
           'shibuya' => 1
           },
     'osaka' => {
           'namba' => 1,
           'kitashinchi' => 1
           },

多次元連想配列を作ったとして、
この「%nihon」自体を削除したいのですが、どのようにしたら良いのでしょうか?

delete %nihon や undef %nihon としても、ループ処理でキーを取り出すと物が残っており困っています。

どうもこの多次元配列自体が「リファレンス」というもで、、、
delete %nihon や undef %nihon はスッゲェ見当外れ、つぅか%nihonは別モンですよ。みたいなとこまではボンヤリわかってきたのですが…。

よろしくお願い致します。

A 回答 (4件)

壱:print "$nihon{'tokyo'}{'nakano'}";


弐:print "$nihon->{'tokyo'}->{'nakano'}";

この二つは別の物です。
壱は$nihon{'tokyo'}->{'nakano'}
弐は$nihon->{'tokyo'}->{'nakano'}
です。

壱を${nihon}{'tokyo'}{'nakano'}
とすれば同じになります。
    • good
    • 0

消え残りについて


Perlでは、その変数への参照がなくならないと確保されているメモリは解放れません。
なので、無名ハッシュのリファレンスが$nihonに代入されていて、
その内部の変数(メモリ)に他から参照がされていなければ、
$nihonをundefすることで、全体を解放することができます。
逆に言えば、なんらかの変数で、その内部に参照が残っていると、$nihonをundefしてもその内部の部分は解放されない場合があります。
おそらくは、そういうことではないでしょうか
例えば、以下のようにして試してみると、
undefの後で、ハッシュの中身が無くなっていることが確認できると思います。
#-------------------------------------------------------------------
$nihon = {
'tokyo' => {
'setagaya' => 1,
'shibuya' => 2
},
'osaka' => {
'namba' => 3,
'kitashinchi' => 4
}};
while(($key, $value) = each( %$nihon )){
print "$key:\n";
while(($k, $v) = each( %$value )){
print "\t$k:$v\n";
}
}
print "$$nihon{'tokyo'}{'shibuya'}\n";

undef $nihon;

while(($key, $value) = each( %$nihon )){
print "$key:\n";
while(($k, $v) = each( %$value )){
print "\t$k:$v\n";
}
}
    • good
    • 0
この回答へのお礼

無事解決致しました。皆様本当にありがとうございました。

悩んだ要因は、

tie (%nihon,'MLDBM',"nihon.db",$mode,0640);

として %nihon にデータベースを関連づけた場合、
print "$nihon{'tokyo'}->{'nakano'}"; で取り出せていたのですが、

このDBを
print FILE Dumper(\%nihon);
としてテキストファイルに出力していたものは、

$nihon = {'tokyo' => {'nakano' => 1,'shibuya' => 1},
'osaka' => {'namba' => 1,'kitashinchi' => 1},};

という宣言文で出力されており、

このテキストファイルを取り込んだ別のcgiだと
print "$nihon{'tokyo'}->{'nakano'}"; では取り出せず、
print "$nihon->{'tokyo'}->{'nakano'}"; でないと取り出せませんでした。

同様に
tie で 取り込んだcgiでは undef %nihon で消えていましたが、
Dumperしたテキストファイルから取り込んだcgiでは undef $nihon で消えるという状態でした。

tie したものも Dumper で取り込んだものもまったく同じもんだと思っていました。
違うんですね、ちょっと意外でした。

良い勉強になりました、リファレンスについて勉強したいと思います。
ありがとうございました。

お礼日時:2005/07/30 04:25

#1お礼>print "$nihon{'tokyo'}{'nakano'}";


えっとですね。
$nihonに格納されているのは、"無名ハッシュへのリファレンス"であるということを頭においておいて下さい。
なので、
print "$$nihon{'tokyo'}{'shibuya'}\n";
の様にアクセスします。
undefされた後で、存在しないデータにアクセスをするとそのこと自体が、新しい変数(ハッシュ)を作ってしまうことになるので注意して下さい。

例えば、質問文のようなハッシュのキーと値を取り出すには、次のようにしてみると良いかも知れません。
while(($key, $value) = each( %$nihon )){
print "$key:\n";
while(($k, $v) = each( %$value )){
print "\t$k:$v\n";
}
}
    • good
    • 0

$nihon に無名ハッシュのリファレンスが格納されているので、



undef $nihon;

とすることで全体のハッシュを削除できます。
この場合、%nihonは、別物です。
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございました。
試してみたのですが、なぜか消えるものと消えないものがございました…。

その法則性を探している時に見つけたのですが、

壱:print "$nihon{'tokyo'}{'nakano'}";
弐:print "$nihon->{'tokyo'}->{'nakano'}";

このような2種類の書き方でprintしたときに、
壱の書き方じゃないと表示されない連想配列、
弐の書き方じゃないと表示されない連想配列、
はたまた壱でも弐でも表示されるものに分かれておりました。

何かに迷い込んだ気分です…。
壱と弐は同等と考えていたのですが、
違うのでしょうか?

お礼日時:2005/07/30 01:32

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!