如何将参数放入查找“想要的函数”并获得返回

时间:2015-05-29 17:19:26

标签: perl

我对perl很新。 我有一个find函数来遍历一个目录结构,它有一个“想要的函数”,为每个找到的文件调用。

我想将参数放入“想要的函数”并返回一个返回值。

我用全局变量解决了这个问题并且它有效,但我不喜欢这些代码; - )

$param1 = "value";
$param2 = "value2";
find(\&wantedFunction , $directory);
print $returnValue;

sub wantedFunction
{ #do something with $param1 and $param2
  $returnValue = f1($param1);";
}

有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

请记住,当您使用File::Find重复呼叫子时,会有多个返回码。我不确定你是否可以轻松地捕获"返回传统意义上的代码。但是,您可以传入包含结果的数组(或范围一)。

将参数传递到回调子(例如在File::FindXML::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返回值; {它很容易使用匿名子例程或闭包ikegamiSobrique描述,但另一个常见的建议是使用像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,
}