包装perl';对象中的排序函数

包装perl';对象中的排序函数,perl,sorting,block,Perl,Sorting,Block,我试图在我的一个(面向对象)包中提供一个排序函数,它接受一个块,并像标准的Perlsort一样提供$a和$b 首先,我在包含包装排序函数的包中尝试执行的操作的简化版本: # In package My::Object sub sort { my $self = shift; my $block = \&{shift @_}; return sort $block @{$self->{arrayRef}}; # I want to use the passed in b

我试图在我的一个(面向对象)包中提供一个排序函数,它接受一个块,并像标准的Perl
sort
一样提供$a和$b

首先,我在包含包装排序函数的包中尝试执行的操作的简化版本:

# In package My::Object
sub sort {
  my $self = shift;
  my $block = \&{shift @_};

  return sort $block @{$self->{arrayRef}}; # I want to use the passed in block with array data contained in this object
}
然后是一个客户端传递一个块的示例,该块定义了要为排序运行的比较器:

my $obj = My::Object->new([3, 1, 5, 6, 2, 4]); # As an example, these values will be come arrayRef from above
my @sortedVals = $obj->sort({ $a < $b });
my$obj=my::Object->new([3,1,5,6,2,4])#例如,这些值将来自上面的arrayRef
my@sortedVals=$obj->sort({$a<$b});
有没有一种方法可以在仍然能够使用Perl的
排序的情况下完成我想做的事情?

主要是

要将裸块用作子例程语法,需要使用
&
。通常,您应该避免原型,但将子例程作为裸块传递是少数可以接受的情况之一。不幸的是,因为它们必须在编译时确定和应用,所以原型不能在方法上工作。因此,您必须使用完整的匿名子例程语法,
sub{…}

my @sortedVals = $obj->sort(sub { $a <=> $b });
local
在块期间创建全局的临时副本,这包括调用的其他子例程,因此这将影响排序。然后,当该方法完成时,该值将恢复为原来的值

Perl全局变量存储在其中,其中包含具有相同名称的所有全局变量<代码>*a
包含
$a
@a
%a
。通过复制调用方的typeglob,当
$My::Object::a
更改时,调用方的
$a
也将更改。它们是别名


*{…}
语法允许您使用另一个变量或表达式按名称获取全局变量。这被称为一个。现在我们可以访问调用方的
*a
。使用这种语法通常是错误的,因此您必须关闭
strict
,否则Perl不会让您这么做。

感谢您在这方面发表的文章。
The*{…}语法按名称引用全局变量。
这似乎是一种描述这种语法的有趣方式——特别是在解释了typeglob是什么之后。该语法是编写typeglob的另一种方式,其中typeglob表示具有指定名称的所有全局变量…..将当前包的所有全局“a”变量,typeglob
*a
,分配给调用方的所有全局“a”变量,typeglob
*{caller.::a'}
导致当前包的全局“a”变量成为调用包的全局“a”变量的别名。这意味着当您更改当前包中的全局“a”变量时,它会更改调用者包中的全局“a”变量。*@7stud Yes,
*{…}
是一个typeglob。这也是一个象征性的参考。我必须解释两者,它们只是在不同的段落中。我叫他们“地球人”,也许我应该用更恰当的名字。
sub sort {
    my $self = shift;
    my $block = shift;

    no strict 'refs';
    local *{caller.'::a'} = *a;
    local *{caller.'::b'} = *b;

    return sort $block @{$self->{arrayRef}};
}