こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Perlスクリプト (); wantarry, (localtime)[0..2]; について。

人様の作ったスクリプトの解析をしています。
下記のスクリプトについて質問があります。


my $now = zikoku();
print "$now です。\n";

sub zikoku {
my ($sec, $min, $hour) = (localtime)[0..2];
if (wantarray) {
return ($hour, $min, $sec);
} else {
return sprintf "%02d:%02d:%02d", $hour, $min, $sec;
}
}



まず、zikoku(); の部分なのですが、現在自分はサブルーチンは&で呼び出すものとしか認識しておらず、ここではどのような用法で使われているのかがわかりません。();は何なのでしょうか??

また、localtime関数の次の[0..2]の意味が分かりません。

そして、wantarray関数自体の働きは一応理解しているのですが、ここではwantarray関数にどのような意味があるのかが分かりません。

分かる方いらっしゃいましたらご教授頂けると幸いです。よろしくお願いします。

投稿日時 - 2006-02-12 22:40:45

QNo.1961928

困ってます

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

戻り値が配列の時・・・というよりは、戻り値として配列を期待されている時に wantarray が真になります。

たとえば No.4 の方が書かれている
my @now = zikoku();
のように、配列に代入する時や、
print zikoku();
の様なケースです。これらはリストコンテキスト(文脈上リストとして解釈される)といいます。

逆に
my $now = zikoku();
はスカラー変数に代入しようとしていますのでスカラーコンテキスト(文脈上スカラーとして解釈される)です。print の例で言うと、
print scalar zikoku();
のように scalar と言う関数を使えばスカラーコンテキストを強制することができます。

戻り値はサブルーチンの中で最後に評価された式の値です。もしくは今回の関数のように return で「これを返すんですよ」と明示してやります。

書物で言えば「初めてのPerl」を読めば用語その他すっきりするのではないでしょうか。(結構歯ごたえがありますが。(^^;)

投稿日時 - 2006-02-13 10:14:22

お礼

なるほど、そういうことでしたか。参考になりました、ありがとうございました!

投稿日時 - 2006-02-13 22:44:38

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.4

>zikoku(); の部分なのですが、現在自分はサブルーチンは&で呼び出すものとしか認識しておらず、ここではどのような用法で使われているのかがわかりません。();は何なのでしょうか??
サブルーチン呼出は、定義がされる前に呼び出す場合、&を付ける必要があります。(単なる文字定数として解釈されてしまうため)
引数無しでサブルーチンを呼び出す場合は、( )は、本来必要ありませんが、この場合、( )があることで、サブルーチン呼出として解釈されます。("()"が付いていることで定数文字列じゃなく関数呼出だとわかる)
>localtime関数の次の[0..2]の意味が分かりません。
配列スライスと言います。
@array[0..2]とすれば
($array[0],$array[1],$array[2])
を表します。
my ($sec, $min, $hour) = (localtime)[0..2];
とすれば、localtimeが返すリストの最初の3つを取り出して左辺のそれぞれに代入することになります。
>ここではwantarray関数にどのような意味があるのかが分かりません。
つまりサブルーチンが配列を要求する場面で使われているか、スカラーを要求する場面で使われているかを判断して、配列の場合配列、スカラーを要求されている場合スカラーを返すために(場面判断のために)使います。
質問文のスクリプトの場合
my $now = zikoku();
は、文字列として要求されているので、サブルーチンは、"hh:mm:ss"を返すということになります。
仮に
my @now = zikoku();
で呼び出されていたら
(h, m, s) を返すということです。
なぜ、わざわざそういうようにするのかというと、この(文字列として要求される)場面だけでなく、他の場面でも使えるように、使い回しが利くように作っているのだと思います。

投稿日時 - 2006-02-13 05:20:07

お礼

分かりやすい説明ありがとうございます!参考になりました。

投稿日時 - 2006-02-13 22:46:15

ANo.3

アレ?私質問の意味を取り違えたでしょうか?

if (ブール値) {
 #ブール値が真の場合
} else {
 #ブール値が偽の場合
}

なので wantarray が真偽を返さないと if 構文が動作しない・・・のですが・・

投稿日時 - 2006-02-13 00:06:26

お礼

すいません、自分まだまだ基礎知識が足りてないです・・。

wantarrayは、実行中のサブルーチンの戻り値として、リストが要求されている場合に真を返し、スカラーが要求されている場合には偽を返す、とウェブ上のリファレンスには載っているのですが(おそらく、話題のサブルーチンを例にして言えば、戻り値が配列の時は ($hour, $min, $sec) を返し、戻り値が変数の場合は sprintf "%02d:%02d:%02d", $hour, $min, $sec を実行して返すということなのだと解釈してますが合ってるでしょうか??)、そもそも「実行中のサブルーチンの戻り値」とは具体的に何を指しているんでしょうか??そこからして理解してなかったです。「戻り値」の定義自体もちょっとよく分かってないかもしれません。。そして、なぜ時刻をブラウザに表示させるのにwantarrayを使わなければいけないのかが分からないのです。

@yobi = ('日', '月', '火', '水', '木', '金', '土');
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon += 1;
print "$year年$mon月$mday日($youbi[$wday]) $hour時$min分$sec秒\n";

上のスクリプトでも出来るのに。なぜわざわざwantarrayを使うのだろう・・・?と。

また なぜ (localtime)[0..2] なのだろう?と。[0..2] って何ですか?と聞くよりは (localtime)[0..2] って何ですか?と聞いたほうが早かったかもしれません。

よろしければご教授おねがいします。

投稿日時 - 2006-02-13 03:05:34

ANo.2

「真を返す」ではなく、
「真の場合には(リストコンテキストの場合)」、($hour, $min, $sec) を返し、
「偽を返す」ではなく、
「偽の場合には(スカラーコンテキストの場合)」、23:33:35 の様な文字列を返すと言うことです。

? は単体で使用されているのではなく、3項演算子
ブール値 ? 真の場合 : 偽の場合
として使用しています。参考URLの条件演算子の項をご覧下さい。

参考URL:http://www.rfs.jp/sb/perl/02/03.html#4.%E8%AB%96%E7%90%86%E6%BC%94%E7%AE%97%E5%AD%90

投稿日時 - 2006-02-12 23:56:33

ANo.1

zikoku();
引数無しでサブルーチン zikoku を呼び出しています。

[0..2]
配列 スライス で検索してみて下さい。0..2 の部分は 0, 1, 2 と同じです。

前回質問されていた時には3項演算子で
wantarray ? 真の場合 : 偽の場合
となってましたが、それが if の構文に変わっただけです。

参考URL:http://www.rfs.jp/sb/perl/index.html

投稿日時 - 2006-02-12 23:04:51

お礼

回答ありがとうございます!
3つ目のwantarrayですが、すいません、質問の仕方が悪かったです。ここでwantarrayを使って、リストが要求されている場合に真を返し、スカラーが要求されている場合には偽を返すことにどのような意味があるのか分からないという意味だったんです。

また、一つ質問を追加させてください。一つ前の質問のことなのですが、wantarray ? の「?」は一体どのような意味を持っているのでしょう??ご教授よろしくお願いしますm()m

投稿日時 - 2006-02-12 23:13:03

あなたにオススメの質問