Perl 如果你在匿名潜水艇内呼叫shift怎么办?
首先,如果这个问题不合适,道歉;我实际上对perl不太了解 我正在调试一些现有的代码,这些代码应该可以将我们的在线作业系统WeBWorK的成绩发送到LMS。我遇到了一个奇怪的错误,我认为有些东西没有正确初始化,或者可能不是正确的类。我怀疑问题可能在这里:Perl 如果你在匿名潜水艇内呼叫shift怎么办?,perl,subroutine,anonymous,Perl,Subroutine,Anonymous,首先,如果这个问题不合适,道歉;我实际上对perl不太了解 我正在调试一些现有的代码,这些代码应该可以将我们的在线作业系统WeBWorK的成绩发送到LMS。我遇到了一个奇怪的错误,我认为有些东西没有正确初始化,或者可能不是正确的类。我怀疑问题可能在这里: sub go { my $self = shift; my $r = $self->r; my $ce = $r->ce; # If grades are begin passed back to
sub go {
my $self = shift;
my $r = $self->r;
my $ce = $r->ce;
# If grades are begin passed back to the lti then we peroidically
# update all of the grades because things can get out of sync if
# instructors add or modify sets.
if ($ce->{LTIGradeMode}) {
my $grader = WeBWorK::Authen::LTIAdvanced::SubmitGrade->new($r);
my $post_connection_action = sub {
my $grader = shift;
# catch exceptions generated during the sending process
my $result_message = eval { $grader->mass_update() };
if ($@) {
# add the die message to the result message
$result_message .= "An error occurred while trying to update grades via LTI.\n"
. "The error message is:\n\n$@\n\n";
# and also write it to the apache log
$r->log->error("An error occurred while trying to update grades via LTI: $@\n");
}
};
if (MP2) {
$r->connection->pool->cleanup_register($post_connection_action, $grader);
} else {
$r->post_connection($post_connection_action, $grader);
}
}
... # a bunch of other stuff happens in the "go" sub
我有点怀疑问题出在$grader变量上;特别是,我不知道我的$grader=shift;在一个匿名的sub里面。比如,如果sub有一个名字,那么shift会给出传递给sub的第一个参数。但是因为它是匿名的,我不知道它认为它的参数是什么
此外,我真的不知道为什么需要这条线。比如,从我的谷歌搜索中,我了解到匿名sub的目的是将周围环境中的所有变量都保留在范围内。那么,为什么我们首先需要在匿名sub中重新定义$grader
谢谢你帮了一个perl noob的忙!: 在这方面,anon subs没有什么特别之处
my $cr = sub {
my $arg = shift;
say $arg;
};
$cr->("foo"); # Prints "foo"
$cr->("bar"); # Prints "bar"
在您的情况下,您将$post\u connection\u action和$grader传递给cleanup\u register或post\u connection,期望它将导致调用&$post\u connection\u action,并将$grader作为其第一个参数。期望是否正确取决于cleanup_register和post_connection的实现,我对此一无所知
请注意,另一个解决方案出现在这里。子运算符在评估子运算符时可以访问范围内的词汇
my $prefix = "> ";
my $cr = sub {
my $arg = shift;
say "$prefix$arg"; # Captures $prefix from sub{} scope.
};
$cr->("foo"); # Prints "> foo"
即使在调用sub时捕获的词汇不再存在,上述情况也是正确的
my $cr;
{
my $prefix = "> ";
$cr = sub {
my $arg = shift;
say "$prefix$arg"; # Captures $prefix from sub{} scope.
};
} # $prefix would normally stop existing here.
$cr->("foo"); # Prints "> foo"
这意味着您不需要通过$grader作为参数。它可以简单地被捕获。只需省去我的$grader=shift;不要将$grader传递给
清理注册或post连接。您的anon sub没有在显示的代码中被调用-它被分配给$post\U connection\u action以供稍后使用。如果您的上一条语句是正确的,则可能是匿名sub中的词法$grader与go中的不同。分级器似乎取决于$self->r的状态。另一方面,匿名子系统外部的$r在其内部使用,因此这不太可能。@simbabque,Re可能是匿名子系统内部的词汇$grader与go中的不同。不,它不能。OP想在潜艇中使用$grader,我向他们展示了如何做到这一点。