我对perl很新。 我有一个find函数来遍历一个目录结构,它有一个“想要的函数”,为每个找到的文件调用。
我想将参数放入“想要的函数”并返回一个返回值。
我用全局变量解决了这个问题并且它有效,但我不喜欢这些代码; - )
$param1 = "value";
$param2 = "value2";
find(\&wantedFunction , $directory);
print $returnValue;
sub wantedFunction
{ #do something with $param1 and $param2
$returnValue = f1($param1);";
}
有更好的方法吗?
答案 0 :(得分:2)
请记住,当您使用File::Find
重复呼叫子时,会有多个返回码。我不确定你是否可以轻松地捕获"返回传统意义上的代码。但是,您可以传入包含结果的数组(或范围一)。
将参数传递到回调子(例如在File::Find
或XML::Twig
中)的一般习惯用法是将其包装在一个匿名子句中 - 传递参数。 (通常,这些论文位于@_
,但File :: Find使用$_
将路径传递给回调。)
E.g。
sub wanted {
my ( $param1, $param2, $path ) = @_;
}
find ( sub { wanted ( "first", "second", $_ ) }, "/path/to/find";
通过这种方式,您可以创建一个只使用一些额外参数调用wanted
的迷你匿名子程序(没有名称)。
为了捕捉结果 - 有各种各样的答案。就个人而言,我认为最简单的是您在wanted
子内更新的结果数组或哈希(具体取决于您正在尝试完成的内容)。
答案 1 :(得分:1)
您可以使用以下内容:
my ($param1, $param2, @found);
sub wanted {
push @found, $_
if is_within_lev_dist($_, $param1, $param2);
}
@found = ();
($param1, $param2) = (..., ...);
find(\&wanted, $dir);
say for @found;
但是那些患有tight coupling。我更喜欢以下内容:
my @found;
find(sub {
push @found, $_
if is_within_lev_dist($_, $param1, $param2)
}, $dir);
say for @found;
is_within_lev_dist
看起来像
sub is_within_lev_dist {
my ($path, $param1, $param2) = @_;
...
return $true_or_false;
}
答案 2 :(得分:1)
人们asked关于从File::Find::find
返回值; {它很容易使用匿名子例程或闭包ikegami和Sobrique描述,但另一个常见的建议是使用像File::Finder
这样的模块,我认为它有一个接口稍微清洁。
以下内容将/tmp
内的路径哈希值创建为与固定字符串相对应的Levenshtein距离:
use strict;
use warnings;
use 5.010;
use Data::Dump;
use File::Find;
use File::Finder;
use Text::Levenshtein qw(distance);
my $start = '/tmp/foo';
my %distances = File::Finder->collect(
sub { $File::Find::name => distance($start, $File::Find::name) },
'/tmp'
);
dd \%distances;
{
"/tmp" => 4,
"/tmp/fie" => 2,
"/tmp/foe" => 1,
"/tmp/foo" => 0,
"/tmp/fum" => 2,
}