2

我在我的主程序中定义了多个类。一个是父类。另一个是儿童班:

# Main Program
...

package Foo;           #Parent class
....

sub glob2regex {
    my $glob = shift;
    ...here be dragons...
    return $regex;
};

....

package Foo::Bar;      #Child Class
base qw(Foo);

sub some_method {
   my $self = shift;
   my $regex = shift;
   my $type  = shift;

   if ( $type eq "glob" ) {
      $regex = glob2regex($regex);   #ERROR: glob2regex is not defined.
   }
   ...
}

我的父类中有一个名为glob2regex. 它不是真正的方法,因为它不对对象做任何事情。相反,它是我的子类可以使用的辅助函数。

但是,如上所示在我的子类中调用它是行不通的,因为它没有在我的子类中定义。我可以在其前面加上完整的父类名称(即,将其称为Foo::glob2regex而不是仅glob2regex),或者我可以将其修改为一个对象,并将其称为$self->glob2regex. 也许有一种更好的方法来处理我忽略的这种情况。

使父类中定义的此类函数在子类中可用的最佳方法是什么?

--

测试程序

#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);
use utf8;

########################################################################
# MAIN PROGRAM 
my $bar = Foo::Bar->new;
$bar->just_foo_it;
#
########################################################################

########################################################################
#
package Foo;

sub lets_foo_it {
    say "I've done foo!";
}
#
########################################################################

########################################################################
#
package Foo::Bar;
use base qw(Foo);

*Foo::Bar::lets_foo_it = *Foo::lets_foo_it;

sub new {
    my $class = shift;
    my $self = {};
    bless $self, $class;
    return $self;
}

sub just_foo_it {
    my $self = shift;

    lets_foo_it();
}
#
########################################################################
4

2 回答 2

4

导出通常使用Exporter完成。

BEGIN {
   package Foo;
   use Exporter qw( import );
   our @EXPORT_OK = qw( glob2regex );
   sub glob2regex { ... }
   ...
   $INC{'Foo.pm'} = 1;
}

BEGIN {
   package Foo::Bar;
   use Foo qw( glob2regex );
   our @ISA = 'Foo';
   ... glob2regex(...) ...
   $INC{'Foo/Bar.pm'} = 1;
}

请注意,类模块导出子例程是非常不寻常的。您应该将其视为一个危险信号,表明可能存在设计缺陷。

于 2013-08-05T21:20:56.497 回答
1

似乎您的问题是:“我如何use在文件中?”。我有一个编译指示我在这种类型的早期开发中使用,但它分解为:

package Foo;
BEGIN { $INC{ __PACKAGE__ . '.pm'} = __FILE__ . ':' . ( __LINE__ - 1 ); }

一旦它在%INC表中,您通常只需使用它就可以了。

请记住, ause是在编译时require与 a 组合的。import定义Foo导入后,您可以创建一个import函数来处理use.

sub import { 
    my $caller = caller;
    return unless $caller->isa( __PACKAGE__ ); 
    {   no strict 'refs'; 
        *{"$caller\::glob2regex"} = *glob2regex{CODE};
    }
}

正如我上面所写的,我在早期开发中使用这种类型的东西——基本上,当我想要一种具有对象关系的“便签本”时。在可维护的代码中,我的偏好是调用Foo::glob2regex(...),或者就像我有时将它插入到一个 util 包中并从那里导出它:

package Foo::Util; 
use strict;
use warnings;
use parent 'Exporter';
our @EXPORT_OK = qw<glob2regex>;

sub glob2regex { ... }
于 2013-08-05T22:43:32.553 回答