ハッシュリファレンスの未定義エラーに悩む - サブルーチン/ハッシュリ/ファレンス

このQ&Aのポイント
  • サブルーチンでの新規ハッシュへの代入ができない問題に悩んでいます。ハッシュリファレンスの未定義エラーが発生します。
  • 質問文章において、サブルーチン側で新規ハッシュへの代入ができないという問題が発生しています。具体的には、ハッシュリファレンスの未定義エラーが発生します。
  • ハッシュリファレンスの未定義エラーに悩んでいます。サブルーチンで新規ハッシュへの代入ができないため、困っています。
回答を見る
  • ベストアンサー

ハッシュリファレンスの未定義

サブルーチン/ハッシュリ/ファレンスで悩んでいます。 my (@r); $r[1]{"A"} = "1-A"; # 代入 &s(\@r); print $r[1]{"A"},"\n"; # 参照 print $r[2]{"B"},"\n"; # 参照 サブルーチン側でできない。 # sub s() { my ($c)=@_; @$c[1]->{"A"} = "1111-AAAA"; # もちろん代入できる @$c[2]->{"B"} = "2-B"; # 代入 これができない(ハッシュリファレンスの未定義エラー) } サブルーチン側で新規ハッシュのところに代入ができないのですが どのようにすればいいのでしょうか。

  • Perl
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.1

@$c[1]->{"A"} とか @$c[2]->{"B"} とかの書き方が問題です。 暇があれば、@$c[2]->{"B"} が何と等価か、演算子の優先順位にもとづいて考てみましょう。 私の場合はそんな事考えるのは無駄と思う怠け者でして、悩まずに済むコードを書きます。 $c->[1]{"A"} = "1111-AAAA"; $c->[2]{"B"} = "2-B"; もしも深く考えたいなら、ヒントは ${$c}[2]{"B"} です。

kanakanji
質問者

お礼

ありがとうございます! ${$c}なんですね。 1次元のときは@$で書いていたので、型グロブが頭から離れませんでした。すっきりです。

関連するQ&A

  • ハッシュのリファレンスを用いた処理

    ActivePerl 5.8 , WinXP SP2の環境です。 Perl スクリプトを用い、ファイルから複数のブロックからなる情報をよみとり、個別のハッシュを作り、それをリファレンスの配列としてまとめて後から参照するという操作をしたいのですが、詰まってしまいました。。 例として読み取るファイルは ---input.txt--------- >1 Jan 1 Feb 4 >2 Mar 9 Apr 3 >3 Oct 8 Nov 4 ------------------ ここから1,2,3の個別のハッシュ {Jan => 1 Feb => 4} {Mar=> 9 Apr =>3} {Oct =>8 Nov =>4} を作成し、それぞれのハッシュのリファレンスの配列をつくり、その後からすべてのハッシュの中身を個別に出力させたいと思いました。 次のようなスクリプトを作成したのですが思ったように作動しません。 use strict; open (IN, "input.txt") or die ("cant open file \n"); my $reff; my @array_of_reff; my %hash; my $count = 0; while(<IN>){ my $line = $_; ######ここでは各ブロックの頭の ">"を認識し、2個目以降であれば直前までで作ったハッシュのリファレンス($reff)を配列@array_of_reffに入れる。 if($line =~ /^>/){ if($count >0){ $reff = \%hash ; push (@array_of_reff, $reff); %hash = (); } $count++; } ########ここではアルファベットが入った行を認識して、ハッシュに追加しています if($line =~ /^[A-Za-z]/){           $line =~ /([A-Za-z]+)\s+/; my $month = $1; $line =~ /\s+(\d+)/; my $day= $1; $hash{$month} = $day;     } ###ここはファイルの最後になったら直前まで作っていたハッシュののリファレンス($reff)を配列@array_of_reffに入れる。 if( eof ){ $reff = \%hash ; push (@array_of_reff, $reff); } } #####ハッシュのリファレンスの配列(@array_of_reff)からもとのハッシュを参照し、ハッシュごとに出力 foreach my $reff_of_hash (@array_of_reff){    print "output";    while( (my $key,my $value) = each %$reff_of_hash ){     print "\n" , $key, " : ", $value, ;    } } このスクリプトを実行すると Nov 4 Oct 8 という3つめのハッシュのなかみが3回出力されてしまいます。自分では3つの別のハッシュをつくっているつもりでも、どうやら1種類しか作れていない、もしくはハッシュが上書きされているようなのですが、原因がわかりません。 この例だけ見るとハッシュのリファレンスを使う必要はないのですが、実際にはもうすこし大きいスクリプトで"ハッシュのリファレンスの配列を他のサブルーチンに渡す"ということを想定しており、これが解決できず先に進めない状態です。 アドバイス、解決法がわかったら教えていただけないでしょうか。

    • ベストアンサー
    • Perl
  • ハッシュのハッシュを実現したい。

    ハッシュのハッシュを行いたいですがうまくいきません。 ◆正しい例 %ultraman = ( TARO => { cpu => "Celeron(266MHz)", memory=> "32MB", hdd => "4.3GB", }, JACK => { cpu => "Pentium2(333Mhz*2)", memory=> "128MB", hdd => "9GB*4", }, ); $name = "JACK"; $item = "cpu"; print "\$ultraman{$name}{$item}=[$ultraman{$name}{$item}]"; exit(0); __END__ ◆このように使えたら便利(要はハッシュの代入でハッシュのハッシュを実現したい) %a=(); %b = ("cpu"=>"aaaa", "memory"=>"bbbb"); $a{'JACK'} = %b; #---> このように代入したい $name = "JACK"; $item = "cpu"; print "\$a{$name}{$item}=[$a{$name}{$item}]"; exit(0); __END__

    • ベストアンサー
    • Perl
  • ハッシュリファレンスの無名変数

    サブルーチンにハッシュリファレンスを渡すために、 以下のようにすると上手く実行されます。 %hash = ( baa => 1, boo => 2 ); test(\%hash); sub test { my %hash = %{shift}; print $hash{baa}; } これを、%hashに格納せずに、 直接渡そうとすると上手くいきません。 test(\( baa => 1, boo => 2 )); 考え方が間違っているのでしょうか。

    • ベストアンサー
    • Perl
  • リファレンスをサブルーチンの戻り値にしてもOKですか?

    ■ サブルーチン内部で処理した結果を格納した、配列、ハッシュ、スカラーなどのデータを戻り値として利用する必要があります。その場合、どうするのが標準的なやり方でしょうか? ■ return (配列へのリファレンス, ハッシュへのリファレンス, スカラー); などとやってしまっても問題はないでしょうか? ■ 下のプログラムを試したところ、予想に反しちゃんと 「31415」と表示されました。 #!/usr/bin/perl -w sub subroutine{ my @a = (3, 1, 4, 1, 5); return \@a; } my $b = subroutine{}; print @$b; ■ サブルーチン内部で使用した変数へのリファレンスをサブルーチン 外で使っていいのだろうか? サブルーチンの処理が終了した時点でサブルーチン内部で使用した 変数はメモリーから消去されるのかと思ったものですから。

    • ベストアンサー
    • Perl
  • 動的ハッシュを作って取り出したいのですが・・・

    お世話になります。 フォームから送られてくるデータを動的に作ったハッシュで参照出来るように取り組んでるんですが、思ったように出来ず思い悩んでおります。 どうすれば、意図した形でデータを取り出すことが出来ますでしょうか my %FORM = ( 'd01' => 'あ', 'd02' => 'い', 'd03' => 'う', 'd04' => 'え', 'd05' => 'お', 'd06' => 'か', 'd07' => 'き', 'd08' => 'く', 'd09' => 'け', 'd10' => 'こ', ); for(sort { $FORM{$a} cmp $FORM{$b} } keys %FORM){ print "$_ = $FORM{$_} \n"; } $list="d01,d02,d03,d04,d05,d06,d07,d08,d09,d10,"; $i=-1; foreach (split/,/,$list){ $i++; $hash{$_}=$i; } for(sort { $hash{$a} <=> $hash{$b} } keys %hash){ print "$_ = $hash{$_} \n"; $view = ${"FORM$_"}; print "$view\n"; }; 最後のprint "$view\n";箇所で、 $list="d01,d02..." を split/,/,$list したので、 $FORM{d01} $FORM{d02} となるようにして、 「あ い う え お」と取り出したいのです。 ご教授のほど、よろしくお願い致します。

    • ベストアンサー
    • Perl
  • ハッシュの中身の表示

    ハッシュの中身の確認ができなくて困っています。 下記のような実行文においてです。 当然、test の戻り値は、スカラーとハッシュです。ハッシュを戻すときには参照渡し記号の\もつけています。 my ($return_code, %hash_data) = test(); 表示しようとすると、 Hash(0x5b04) のような表示にしかなりません、、 (試した表示方法は、下記4つです。) (環境は、WindowsXP上での、ActivePerl-5.10.0.1004 です。) foreach $key ( keys( %Hash ) ) { print "キー値 : $key\n"; print "値 : $Hash{$key} \n " } while ( ( $key , $value ) = each %Hash ){ print "キー値 : $key\n"; print "値 : $value \n " ; } use Data::Dump qw(dump); print dump(\%hash); #print %display_test; 宜しくお願いします。

    • ベストアンサー
    • Perl
  • リファレンスについて。

    以下のperlスクリプトで、どちらも私には同じ結果をもたらすものだと 予想していたのですが、出力結果が異なってしまいます。 なぜ script1 ではエラーなしで動作するのに、script 2では エラーが出るのでしょうか。 $$xx が d になり、 $$yy が ARRAY(0x180c460) となる理由も わかりません。 稚拙な質問で申し訳ありませんが、どなたかよろしくお願いしますm(_ _)m ## script 1 とします。 my $xx = \qw(a b c d); print "$$xx \n"; # d と出力される print "xx is $$xx \n"; # xx is d と出力。 ## script 2 とします。 my @array = qw(a b c d); my $yy = \@array; print "$yy \n"; # ARRAY(0x180c460) と出力される。 print "yy is $$yy \n"; # Not a SCALAR reference at tryme.pl line 11. とエラーになる。

    • ベストアンサー
    • Perl
  • SW:ハッシュ法によるデータの探索に関する問題

    SW受験予定者です。 問題の解法として理解できない点がありましたので、ご理解のある方はご教授のほどお願い致します。 問.ハッシュ法によるデータの探索に関する記述のうち、最も適切なものはどれか。 答.ウ ハッシュ関数h(x)がh(x)=x mod n (xはキー、nはハッシュ表の大きさ)である場合、キー値がaであるデータと、キー値がbであるデータの間にシノニムが発生するときには、a-bがnの倍数であるという関係が成り立つ。 解答 キーaとキーbを a=s・n+c 、 b=t・n+cとする(s、t、cはともに整数) a-b=(s・n+c)-(t・n+c)=(s-t)・nとなり、これはnの倍数となっているので ウ が正解である。 以上の部分で、a=s・n+c 、 b=t・n+c をどのように導いたのかが理解できません。宜しくお願い致します。

  • ハッシュのハッシュのソート

    rubyでハッシュのソート方法についてはいくつか情報のサイトを見つけられました。 ですが今やりたいのは、ハッシュのハッシュのソートなのですが、うまいやり方がわかりませんでした。 具体的には、 h1 = {"user1"=>{"a"=>10, "b"=>20, "c"=>30"}, "user2"=>{"d"=>5, "e"=>8}, "user3"=>{"f"=>10, "g"=>5, "h"=>10} } というようなハッシュのハッシュを想定しています。ユーザごとに案件ごとの必要工数(時間)をハッシュとして持たせ、全工数が多いユーザ順にソートしたいのです。 上記の場合だと、 {"user1"=>{"a"=>10, "b"=>20, "c"=>30"}, "user3"=>{"f"=>10, "g"=>5, "h"=>10}, "user2"=>{"d"=>5, "e"=>8} } というようにソートしたいのですが、何かやり方がありましたらご教授いただけますでしょうか。

    • ベストアンサー
    • Ruby
  • 配列を引数とするサブルーチンに関する質問

    配列を引数とするサブルーチンに関する質問です。 Trimと Hex2Decのサブルーチンをインターネットを参考に作りました。 下記のスクリプトは > perl test.pl で期待通りに動きます。 質問は、サブルーチンの中における、 for (@out) { $_=hex; } です。 trimの方では、$_がなくても、きちんと動きます。(あってもOK、$_=~s/^\s+//; $_=~s/\s+$//;) Hex2Decの方は、$_=hex; でないと動きません。 これは、for (@out) { }でひとつずつ処理する対象が、$_に入っている。 処理結果の格納先が、s/^\s+//; の場合は、記述無き時は、 $_と暗黙できまっているのに対し、 hex;の場合は、そうではない。明示的に与えてやらなければいけない。 こういう理解で、良いでしょうか? 他に、やりようはあるのでしょうか? 宜しくお願いいたします。 test.pl ----------------------------------------- $a=10,print "Hex=".$a." --> Dec=".&Hex2Dec($a)."\n"; $a=20,print "Hex=".$a." --> Dec=".&Hex2Dec($a)."\n"; @a=('a','b','c','d'); @b=&Hex2Dec(@a); print "Hex=@a --> Dec=@b\n"; $a=' a ',print "org=$a --> trimed =".&trim($a)."xxxxx\n"; $a=' b ',print "org=$a --> trimed =".&trim($a)."xxxxx\n"; @a=(' a ',' a ',' a ',' a '); @b=&trim(@a); print "org=@a --> trimed= @b\n"; sub trim { my @out = @_; for (@out) { s/^\s+//; s/\s+$//; } return wantarray ? @out : $out[0]; } sub Hex2Dec { my @out = @_; for (@out) { $_=hex; } return wantarray ? @out : $out[0]; } ------------------------------------------------

    • ベストアンサー
    • Perl

専門家に質問してみよう