アプリ版:「スタンプのみでお礼する」機能のリリースについて

Perl初心者です。
「Learning Perl」(オライリー社、第5版)を勉強中なのですが、4章の練習問題3でつまずいています。

#!/usr/bin/perl
use strict;

sub total {
my $sum;
foreach (@_) {
$sum += $_;
}
$sum;
}
sub average {
if(@_ == 0) {return}
my $count = @_;
my $sum = total(@_);
$sum/$count;
}
sub above_average {
my $average = average(@_);
my @list;
foreach my $element (@_) {
if($element > $average) {
push @list, $element;
}
}
@list;
}

my $average = average(100, 1..10);
print "\$average = $average\n";
my $barney = above_average(100, 1..10);
print "\$barney = $barney\n";


とやったのですが、結果が

$average = 14.0909090909091
$barney = 1

となってしまいます。
($averageの値は正しいのですが、$barneyの値が100となってほしいのに、1になってしまっています。)
すみませんが、識者の方、どこが悪いのか、ご教授お願いします。

A 回答 (2件)

above_average では、「@list」すなわち、平均値以上の値を持つ要素の配列を返してます。


一方、その呼び出し部では「my $barney = above_average(100, 1..10);」で、$barney というスカラー変数で受けています。

配列をスカラーコンテキストで評価すると、その配列の要素数になりますので、
$barney には、above_average の結果の「平均値以上の値を持つ要素の数」が代入されます。
つまり、1になります。

「100」すなわち、結果の最初の要素を得たいのなら、
---ここから---
my($barney) = above_average(100, 1..10);
---ここまで---
これで、「($barney)」という配列に、above_average の返した配列が代入されますので、
$barney には、その最初の要素である100が代入されます。

あるいは、平均以上の要素を全て表示したいのなら、
---ここから---
my @barney = above_average(100, 1..10);
print "\@barney = @barney\n";
---ここまで---
のように配列変数で受けてください。
    • good
    • 0
この回答へのお礼

さっそく素晴らしい回答をくださいまして、ありがとうございました。

本のページ上でも、ちゃんと
my @barney = above_average(100, 1..10);
print "\@barney = @barney\n";
となっていました。

@を$と一文字書き間違えてただけで、コンパイルエラーにもならずに全然違った結果が得られるんだということを、身に染みて理解できました。
たいへん勉強になりました。ありがとうございました。

お礼日時:2011/04/09 22:08

リストをスカラーに代入すれば、リストの長さが入ります。

    • good
    • 0
この回答へのお礼

回答、ありがとうございました。

お礼日時:2011/04/09 22:13

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