所以我有一个Perl课程.它有一个sort()
方法,我希望它与内置sort()
函数或多或少相同:
$object->sort(sub ($$) { $_[0] <=> $_[1] });
Run Code Online (Sandbox Code Playgroud)
但我做不到:
$object->sort(sub { $a <=> $b });
Run Code Online (Sandbox Code Playgroud)
因为范围.但是List :: Util模块可以实现这一点reduce()
.我查看了List :: Util模块,他们做了一些相当讨厌的事情no strict 'vars'
来实现这一点.我试过了,但无济于事.
我的理解是reduce()
按照它的方式工作,因为它被导出到适当的命名空间,因此我的类不能这样做,因为该函数在另一个命名空间中非常牢固.这是正确的,还是有一些(无疑是更可怕和不明智的)方式在我的情况下这样做?
那么,另外两个答案都是半对的.这是一个实际排序的工作解决方案:
package Foo;
use strict;
use warnings;
sub sort {
my ($self, $sub) = @_;
my ($pkg) = caller;
my @x = qw(1 6 39 2 5);
print "@x\n";
{
no strict 'refs';
@x = sort {
local (${$pkg.'::a'}, ${$pkg.'::b'}) = ($a, $b);
$sub->();
} @x;
}
print "@x\n";
return;
}
package main;
use strict;
use warnings;
my $foo = {};
bless $foo, 'Foo';
$foo->sort(sub { $a <=> $b });
# 1 6 39 2 5
# 1 2 5 6 39
Run Code Online (Sandbox Code Playgroud)
据推测,你可以对一些实际上属于对象的数据进行排序.
你需要caller
魔法,所以你要本地化,$a
并$b
在调用者的包中,这是Perl将要寻找它们的地方.它正在创建仅在调用该子时存在的全局变量.
请注意,您将获得"仅使用一次"的名称warnings
; 不管怎样,我确信你可以通过一些箍来避免这种情况.