use*_*909 11 sorting perl namespaces
假设我有一个other包含子程序(sort_it)的实用程序库(),我想用它来返回任意排序的数据.它可能比这更复杂,但这说明了关键概念:
#!/usr/local/bin/perl
use strict;
package other;
sub sort_it {
my($data, $sort_function) = @_;
return([sort $sort_function @$data]);
}
Run Code Online (Sandbox Code Playgroud)
现在让我们在另一个包中使用它.
package main;
use Data::Dumper;
my($data) = [
{'animal' => 'bird', 'legs' => 2},
{'animal' => 'black widow', 'legs' => 8},
{'animal' => 'dog', 'legs' => 4},
{'animal' => 'grasshopper', 'legs' => 6},
{'animal' => 'human', 'legs' => 2},
{'animal' => 'mosquito', 'legs' => 6},
{'animal' => 'rhino', 'legs' => 4},
{'animal' => 'tarantula', 'legs' => 8},
{'animal' => 'tiger', 'legs' => 4},
],
my($sort_by_legs_then_name) = sub {
return ($a->{'legs'} <=> $b->{'legs'} ||
$a->{'animal'} cmp $b->{'animal'});
};
print Dumper(other::sort_it($data, $sort_by_legs_then_name));
Run Code Online (Sandbox Code Playgroud)
由于一个微妙的问题,这不起作用. $a并且$b是包全局变量.他们指$main::a和$main::b当在封闭包裹起来.
我们可以通过说,而不是:
my($sort_by_legs_then_name) = sub {
return ($other::a->{'legs'} <=> $other::b->{'legs'} ||
$other::a->{'animal'} cmp $other::b->{'animal'});
};
Run Code Online (Sandbox Code Playgroud)
这有效,但迫使我们在各处硬编码我们的实用程序包的名称.如果要改变,我们需要记住改变代码,而不仅仅是use other qw(sort_it);可能存在于现实世界中的陈述.
您可能会立即考虑尝试使用__PACKAGE__.最终评估为"主要".那样做eval("__PACKAGE__");.
使用caller它有一个技巧:
my($sort_by_legs_then_name) = sub {
my($context) = [caller(0)]->[0];
my($a) = eval("\$$context" . "::a");
my($b) = eval("\$$context" . "::b");
return ($a->{'legs'} <=> $b->{'legs'} ||
$a->{'animal'} cmp $b->{'animal'});
};
Run Code Online (Sandbox Code Playgroud)
但这是相当黑魔法的.似乎应该有更好的解决方案.但我还没有找到它或者想出来.
使用原型(最初由ysth在Usenet发布中提出的解决方案).
适用于Perl> = 5.10.1(之前不确定).
my($sort_by_legs_then_name) = sub ($$) {
my ($a1,$b1) = @_;
return ( $a1->{'legs'} <=> $b1->{'legs'} ||
$a1->{'animal'} cmp $b1->{'animal'});
};
Run Code Online (Sandbox Code Playgroud)
我得到的结果是:
$VAR1 = [
{
'legs' => 2,
'animal' => 'bird'
},
{
'legs' => 2,
'animal' => 'human'
},
{
'legs' => 4,
'animal' => 'dog'
},
{
'legs' => 4,
'animal' => 'rhino'
},
{
'legs' => 4,
'animal' => 'tiger'
},
{
'legs' => 6,
'animal' => 'grasshopper'
},
{
'legs' => 6,
'animal' => 'mosquito'
},
{
'legs' => 8,
'animal' => 'black widow'
},
{
'legs' => 8,
'animal' => 'tarantula'
}
];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
368 次 |
| 最近记录: |