perlでカレンダーを出力する方法とその動作についての疑問

このQ&Aのポイント
  • perlでカレンダーを出力する方法とその動作についての疑問です。検索して見つけたページには、Calendar::Simpleを使ったサンプルがありますが、その動作が理解できません。
  • 特に、foreach (@month)の部分での@$_の意味や、print @month[1]での出力結果について疑問があります。
  • 質問記事の中で、perlでカレンダーを出力する方法やその動作について調べていますが、いくつか疑問が生じました。特に、foreach (@month)の部分での@$_の意味や、print @month[1]での出力結果について教えてください。
回答を見る
  • ベストアンサー

どうしてそうなるのかわからない

perlでカレンダーを出力したいと思い検索すると下記のページがヒットしました Calendar::Simple - シンプルなカレンダーを作る為のPerl拡張 http://perldoc.jp/docs/modules/Calendar-Simple-1.07/Simple.pod このページにCalendar::Simpleを使ったサンプルが提示されているのですが、その動作が理解できません。最後の部分なのですが foreach (@month) { print map { $_ ? sprintf "%2d ", $_ : ' ' } @$_; print "\n"; } @$_というのがわかりません。手元のポケットリファレンスには載っていませんでした。@$_はここでは@monthのことを指しているのでしょうか? とすると、まず@monthから一個要素を取り出して、そこに値が存在すればsprintfするということでよいでしょうか? もうひとつあります。@monthの中に何が入っているのか調べようと、 print @month[1]; とすると ARRAY(0x1afe81c)ARRAY(0x1afea20)ARRAY(0x1afe81c)ARRAY(0x1afea20)ARRAY(0x1afe81c) と意味不明な文字列が出力されます。これはどういうことなのでしょうか? よろしくお願いします。

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

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

参考URLの中身を観てませんが、 質問文から @monthの中身は、配列のリファレンスの配列なのでしょう つまり、 @month =( [ 1 .. 31],[1 .. 28],[1 .. 31],[1 .. 30] ); のような感じ(上記は、1~4月)になっているのだと思います。 [ 1, 2, 3, 4]のようなものは、無名配列といって配列のリファレンス(参照)で、普通 @ary = (1, 2, 3, 4); のように配列は、書きますが、 配列のリファレンスの場合は、 $aref = [ 1, 2, 3, 4]; のように、変数としては、スカラー(単体の変数)です。 リファレンスとは、このように、配列の有り場所の場所という1つの実体を指すものなので、スカラーなのです。 そうした配列の有り場所を指す変数を配列として扱うには、 @$arefのように@を付けてやりますこれをデリファレンスといいます。 つまり、 @$_ の部分では、配列のリファレンスの配列から1つのリファレンスを取り出し、配列に戻してやっているということです。 map の中の$_は、@$_ とした時の 配列の中身の1つです。 変数をprintした時 >ARRAY(0x1afe81c) のように表示されたら、それは、配列(ARRAY)のリファレンスが格納されているということです。 サンプル: 1) $ref = [ 1 , 2, 3, 4, 5 ]; print map { $_ ? sprintf "%2d ", $_ : ' ' } @$ref; 2) $ref = [ 1 , 2, 3, 4, 5 ]; foreach (@$ref){ print "$_\n"; } 3) @ary = ( 1 , 2, 3, 4, 5 ); foreach (@ary){ print "$_\n"; } 4) @ary = ( [1,2] , [2, 3], [3, 4] ); foreach (@ary){ print map { $_ ? sprintf "%2d ", $_ : ' ' } @$_; print "\n"; }

tochanx
質問者

お礼

理解できました!わかりやすい説明、サンプルをありがとうございました! 「配列のリファレンスの配列」という表現がリンク先にもあったのですが、よくわからなかったのです。なるほど、こういうことでしたか。 助かりました・・・

関連するQ&A

  • リファレンスについて。

    以下の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
  • 行指向処理でデータの読み込みについて(@_)

    perl初心者です。 ファイルからデータを読み込んで3列目の要素を取り出すプログラムを作ろうと思っています。 その途中の勉強段階で参考書に $,=','; $\="\n"; @ARRAY=(); while(<>){ chop; split; @ARRAY=(@ARRAY, [@_] ); } print @ARRAY; foreach (@ARRAY){ print @$_; } print $ARRAY[1][2]; というプログラムがありました。このプログラムの大まかな意味は理解できます。 しかし、読み込ませるファイルを 1 2 3 4 5 6 7 8 9 のようにして コマンドプロンプトで実行してみると ARRAY(0x198b9c),ARRAY(0x198998),ARRAY(0x19a830) となり、参考書で紹介される結果の ARRAY(0x198b9c),ARRAY(0x198998),ARRAY(0x19a830) 1,2,3 4,5,6 7,8,9 6; となりませんでした。色々調べたんですが、どうやら print @_; に反応(?)してくれてないみたいです。 私の使用しているPCはwindows7です。原因がわからず先に進めない状況です。指導お願い致します。

    • ベストアンサー
    • Perl
  • ファイルの入出力と改行

    縦100文字横70文字のデータが入ったデータファイルを横50文字にして並べ直したいと思い、まず試しに標準出力でそれがうまくいくかやってみたのですが、うまくいきません。もしお分かりであれば教えていください。よろしくお願いいたします。 #! /usr/bin/perl $filename = "reference.txt"; open HANDLE, "<$filename" or die "cannot open :$!"; print "open success\n"; @array = <HANDLE>; $count = 1; foreach $var (@array) { chomp $var; # print $var; if($count==50){ print $var, "\n"; } else{ print $var; } $count++; } close HANDLE; print "\n";

    • ベストアンサー
    • Perl
  • サンプルの意味

    お世話になります。 あるサイトで下記のようなサンプルをみつけました。 ------------------------------------------------------------- use SOAP::Lite; use MIME::Entity; my $soap = SOAP::Lite ->uri($NS) ->proxy($HOST); my $som = $soap->foo(); ★foreach my $part (${$som->parts}) { ★ print $part->stringify; } ------------------------------------------------------------- 実際に動かしてみたのですが"Not a SCALAR reference"エラーで動きません。 実のところあまり意味がわかっていなかったので、どのような動きかを調べてみましたが、★のところがわかりませんでした。 ★の部分などは、perlの一般的な書き方だと思っていたのですが、調べた限り意味がわかりません。 これはどういう意味なのでしょうか?ご教授いただけたらと思います。 $som->partsをprintすると、"ARRAY(0xxxxx)"が出力されます。 普通の配列を出力してもARRAY(0xxxx)とは出力されませんよね?これはどういう意味なんだろう・・・

    • ベストアンサー
    • Perl
  • リファレンスを使った方法を教えて下さい。

    以下例1.例2のサブルーチンの部分についてリファレンスを使った書きかたを教えて下さい。よろしくお願いします。 例1. @array1 = ('111x111', '22y2'); $str1 = 'x'; print "find '$str1': ",sagasu($str1,@array1), "\n"; @array2 = ('333x333', '44y4', '555'); $str2 = 'y'; print "find '$str2': ",sagasu($str2,@array2), "\n"; @array3 = ('666x666', '77y7'); $str3 = 'z'; print "find '$str3': ",sagasu($str3,@array3), "\n"; sub sagasu { my ($what,@area) = @_; foreach my $idx (0..$#area) { if ($area[$idx] =~ /$what/) { return $idx } } return -1; } 例2.参照(perlの引数が不安定になります。http://okwave.jp/qa1958086.html) @array1 = ('111x111', '22y2'); $str1 = 'x'; print "find '$str1': ",sagasu(@array1,$str1), "\n"; @array2 = ('333x333', '44y4', '555'); $str2 = 'y'; print "find '$str2': ",sagasu(@array2,$str2), "\n"; @array3 = ('666x666', '77y7'); $str3 = 'z'; print "find '$str3': ",sagasu(@array3,$str3), "\n"; sub sagasu { (@area, $what); (@area[0..($#_ - 1)], $what) = @_; foreach my $idx (0..$#area) { if ($area[$idx] =~ /$what/) { return $idx } } return -1;

    • ベストアンサー
    • Perl
  • ハッシュのリファレンスを用いた処理

    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
  • Perlの部分的なHTML出力

    調べてみたんですがちょっと探し当てられなかったので教えてください。 HTMLファイルの中である一部分だけPerlによる出力でページを表示させたいのですが、それは可能でしょうか? 自分なりに調べて試してみたのは、HTMLで<IMG>タグをつかってPerlを呼び出し、Perlにprint文で出力を書けばいいのかな? とやってみましたが、できません。 全てPerlで出力するしか方法はないのでしょうか? ご解答お願いします

  • Perl:ファイルハンドルをスカラー変数にすると変

    お世話になります。 Perlの書き方について教えてください。 Perlのファイルハンドルで、昔はINやOUTやFILEのようにベアワード(裸のワード)を使っていたと思います。 ★(プログラム1) #! /bin/perl # # fh_bareword.pl use strict; use warnings; open IN, '<', 'in.txt'; open OUT, '>', 'out.txt'; while (<IN>) { print OUT; } close IN; close OUT; ★(実行例) C:\Perl\perl>type in.txt This is a pen. That is a book. C:\Perl\perl>fh_bareword.pl C:\Perl\perl>type out.txt This is a pen. That is a book. ★★★ ところが、これだとIN、OUTがグローバル名になってしまい、他のモジュールと衝突することがあるということで、myつきのスカラー変数にした方が良いと言われました。 それで、以下のように書いてみましたが、想定のように動作しません。 ★(プログラム2) #! /bin/perl # # fh_scalar.pl use strict; use warnings; open my $in, '<', 'in.txt'; open my $out, '>', 'out.txt'; while (<$in>) { print $out; } close $in; close $out; ★(実行例) C:\Perl\perl>fh_scalar.pl GLOB(0x146ea34)GLOB(0x146ea34) C:\Perl\perl>dir out.txt ドライブ C のボリューム ラベルは eMachines です ボリューム シリアル番号は 89C9-F870 です C:\Perl\perl のディレクトリ 2013/07/09 23:05 0 out.txt 1 個のファイル 0 バイト 0 個のディレクトリ 23,226,032,128 バイトの空き領域 ★★★ たぶん print $out; の部分で、私はファイルハンドル$outに$_を表示してくださいと意図していたのですが、「ファイルハンドルSTDOUTに$outを表示してください」という意図に受け取られたらしく、上記のようにGLOBのリファレンス?が表示されてしまいました。 print $out $_; と書くと、確かに正しく表示されますが、これが正しい書き方なのでしょうか。 printの後ろに来るのは出力する文字列ではなくファイルハンドルだと、正しく判断してもらえるもっと美しい書き方はあるのでしょうか。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • Net::FTP使用時の取得値をどうやって取得するのですか

    perlでftpをしたいので調べたら以下のようなページを見つけました。 http://perldoc.jp/docs/modules/libnet-1.12/Net/FTP.pod 接続 $ftp = Net::FTP->new("some.host.name", Debug => 0); ログイン $ftp->login("anonymous",'-anonymous@'); のようにしていけばいいのはわかったのですがpwdなどのコマンドの場合 「返します」と書いてあるんですが、どうすれば取得できるのかわかりません。 たとえばpwdであれば $ftp->pwd(); だと思うのですが、その結果はどうとるのでしょうか・・・ $ftpのなかかと思ったのですが、 print $ftp とすると Net::FTP=GLOB(0x8067224) と出てきました・・・ あとコネクトも成功、失敗はどうしたらわかるのでしょうか。

    • ベストアンサー
    • Perl
  • ハッシュキーの内容について

    こんばんは。perlをはじめて一ヶ月あまりの初心者です。 また疑問に思うことが見つかり、質問させていただきました。 以下のようなコードがあります。 ----------------------------------------- my @array = ( 'a','b','c'); my %hash; for (@array) {   $hash{$_}{OK} = 1;   $hash{$_}{WAVE} = 2;   $hash{$_}{Perl} = 3; } print $hash{a}->{OK}; print $hash{"b"}->{WAVE}; print $hash{c}->{"Perl"}; ----------------------------------------- 1、2、3を格納するときなのですが、 ハッシュのキーになる値(OK、WAVE、Perl)は、 ダブルクォートや、シングルクォートで囲っていません。 でも、エラーも発生せず、普通に実行できてしまいます("123"を表示します)。 ハッシュのキーは、 "OK","WAVE"や、'Perl'のように ダブルクォートや、シングルクォートで 囲む必要はないのでしょうか?? C言語みたいに厳密に型が決まっているわけではないので、 OKでも"OK"でもよいのかなー、という思いはあるのですが、、、 よろしくお願いします。

    • ベストアンサー
    • Perl

専門家に質問してみよう