1

2 つの引数を取る1 つの関数があります。1 つsub _where(\@ \&)目は配列で、2 つ目は別の関数にする必要があります。この他の関数はブール値を返します。関数の for ループ内で呼び出したいと思いsub _where(\@ \&)ます。

カスタム ローカル名に渡す関数を抽出するのに問題があります。関数にさまざまなブール関数を渡すことができるはずなので、ローカル名が必要だと思いwhereます。

どこ:

sub _where(\@ \&)
{
    my @stud = @{$_[0]};
    my $student;
    my $function = shift;
    my $bool = 0;
    my $i;

    for $i(0..$#stud)
    {
        my $student = $stud[$i];
        function $student;
    }
}

渡す必要がある Function1:

sub name_starts_with($)
{
    my $letter = 'B'; 
    my $student = shift;
    my $first;

    $first = substr($student -> name, 0, 1);

    if($first eq $letter)
    {
        return 1;
    }
}

Function2 に渡す必要がありますwhere:

sub points_greater_than($)
{
    my $sum_pts = 5; 
    my $student = shift;
    my $pts;

    $pts = $student -> points;
    if($pts > $sum_pts)
    {
        return 1;
    }
}

皆さんがここで私を助けてくれることを願っています。乾杯

4

6 に答える 6

2

1 つの問題は、パラメーターの取得方法にあります。

my @stud = @{$_[0]};  # <-- this doesn't remove first parameter from list
my $student;
my $function = shift; # <-- therefore you'll still get first parameter, not second

この修正を試してください:

my $function = $_[1]; # always get second parameter

アップデート

関数への参照を他の関数に渡す方法の例を追加します。

_where(\@stud, \&name_starts_with);
于 2013-04-09T23:28:13.880 に答える
1

最初の引数の取得に関する問題を解決した後、コード参照からサブルーチンを呼び出す 3 つの方法を以下に示します。

&$function($student);    # uses the fewest characters!

&{$function}($student);  # the style you're using for the array ref

$function->($student);   # my favorite style

perlrefのman ページを読むと、より詳細な情報を見つけることができます。

于 2013-04-10T00:08:58.930 に答える
1

coderef が最初になるように引数の順序を変更すると、コードはもう少し Perlish になります。

sub _where(\&@){
  my $func = shift;
  my @return;

  for(@_){
    push @return, $_ if $func->($_);
  }

  return @return;
}

あなたが Perl に精通していれば、私がgrep(不十分に) 再実装しただけであることに気付くでしょう。

sub name_starts_with{
    'B' eq substr($_->name, 0, 1);
}

sub points_greater_than{
    $_->points > 5;
}

my @b_students = _where( &name_starts_with, @students );

my $count_of_students_above_5 = _where( &points_greater_than, @students );

これらのサブルーチンは に依存するようになったので$_、単に を使用する必要がありますgrep

my @b_students = grep( &name_starts_with, @students );

my $count_of_students_above_5 = grep( &points_greater_than, @students );

それらのサブルーチンも非常に短いので、ブロックだけを使用するのはどうでしょうか。

my @b_students = grep {
  'B' eq substr($_->name, 0, 1)
} @students;

my $count_of_students_above_5 = grep {
  $_->points > 5;
} @students;
于 2013-04-11T04:35:53.020 に答える
1

function の引数処理にバグがあります_where。配列参照を$function変数に入れています。あなたがしなければなりません

my @stud = @{shift()};
my $student;
my $function = shift();

また

my @stud = @{$_[0]};
my $student;
my $function = $_[1];

または私が好む

sub _where(\@ \&)
{
    my ($stud, $function) = @_;

    for my $student (@$stud)
    {
        $function->($student);
    }
}

ただし、これらの方法を混在させないでください。

于 2013-04-09T23:29:11.050 に答える