如何从File :: Find回调中将新字段插入到Perl中的$ self中

时间:2011-03-31 15:19:48

标签: perl oop

在Perl对象中,我正在尝试从File :: Find $self sub中向wanted()添加一个新字段。

use File::Find;

sub _searchForXMLDocument {
    my ($self) = @_; 
    if($_ =~ /[.]+\.xml/) {
        $self->{_xmlDocumentPath} = $_;
    }
}


sub runIt{
    my ($self) = @_;
    find (\&_searchForXMLDocument, $self->{_path});
    print $self->{_xmlDocumentPath};
}

_searchForXMLDocument()$self->{_path}内搜索XML文档,并且应该将该XML路径附加到$self->{_xmlDocumentPath},但是当我尝试打印它时,它仍然未初始化。如何在$self中添加字段?

Use of uninitialized value in print at /home/scott/workspace/CCGet/XMLProcessor.pm line 51.

3 个答案:

答案 0 :(得分:3)

您没有以OO方式调用_searchForXMLDocument(),因此您的$ self对象不会传递给它。这应该是现在的诀窍。为您的方法使用闭包,您可以访问$ self;

sub runIt{
    my ($self) = @_;

    my $closure = sub {
        if($_ !~ m/[.]+\.xml/) {
            $self->{_xmlDocumentPath} = $_;
        }
    };

    find(\&$closure, $self->{_path});
    print $self->{_xmlDocumentPath};
}

答案 1 :(得分:3)

find()的第一个参数需要携带两条信息:测试条件和您正在使用的对象。这样做的方法是关闭。 sub { ... }创建了一个代码引用,就像从\&_searchForXMLDocument获得的那样,但是闭包可以访问封闭范围中的词法变量,因此当前对象($self)与闭包相关联

sub _searchForXMLDocument {
    my ($self) = @_;
    if($_ =~ /[.]+\.xml/) {
        $self->{_xmlDocumentPath} = $_;
    }
}


sub runIt{
    my ($self) = @_;
    find (sub { $self->_searchForXMLDocument (@_) }, $self->{_path});
    print $self->{_xmlDocumentPath};
}

答案 2 :(得分:2)

我认为你正在寻找这样的东西:

package XMLDocThing;
use strict;
use warnings;
use English    qw<$EVAL_ERROR>;
use File::Find qw<find>;
...

use constant MY_BREAK = do { \my $v = 133; };

sub find_XML_document { 
    my $self = shift;
    eval { 
        find( sub {
                 return unless m/[.]+\.xml/;
                 $self->{_xmlDocumentPath} = $_;
                 die MY_BREAK;
              }
            , $self->{_path} 
            );
    };
    if ( my $error = $EVAL_ERROR ) { 
        die Carp::longmess( $EVAL_ERROR ) unless $error == MY_BREAK;
    }
}

...
# meanwhile, in some other package...

$xmldocthing->find_XML_document;

您传递一个闭包来查找,它可以从包含范围访问$selfFile::Find::find无法像对象那样传递行李。