首先,如果这个问题不适当地表示歉意;我实际上并不了解很多Perl。
我正在尝试调试一些现有代码,这些代码应该将名为WeBWorK的在线作业系统中的成绩发送给LMS。我遇到了一个奇怪的错误,我认为某些东西没有正确初始化,或者不是正确的类。我怀疑问题可能出在这里:
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
变量上。特别是,我不知道my $grader = shift;
匿名子内部有什么作用。就像,如果子对象具有名称,则将shift
传递给子对象的第一个参数会更清楚。但是由于它是匿名的,所以我不知道它的论点是什么。
此外,我不太确定为什么根本需要该行。就像我从谷歌搜索中了解到,匿名子程序的作用是将周围环境中的所有变量都保留在范围内。那么,为什么我们首先需要$grader
在匿名子内部重新定义?
感谢您帮助Perl新手!:)
在这方面,无用潜艇没什么特别的。
my $cr = sub {
my $arg = shift;
say $arg;
};
$cr->("foo"); # Prints "foo"
$cr->("bar"); # Prints "bar"
在你的情况,你通过$post_connection_action
,并$grader
于cleanup_register
或post_connection
与预期,这将导致调用&$post_connection_action
与$grader
作为第一个参数。无论期望是正确与否取决于执行cleanup_register
和post_connection
,而我什么都不知道。
请注意,此处提供了另一种解决方案。在sub
评估运算符时,Sub可以访问范围内的词汇。
my $prefix = "> ";
my $cr = sub {
my $arg = shift;
say "$prefix$arg"; # Captures $prefix from sub{} scope.
};
$cr->("foo"); # Prints "> foo"
即使在子程序被调用时否则捕获的词汇将不再存在的情况下,上述情况也是正确的。
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
作为参数传递。它可以简单地被捕获。只需省去my $grader = shift;
(不要传递$grader
给cleanup_register
或post_connection
)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句