将函数/子例程导入子类

时间:2014-08-28 10:59:52

标签: perl moops

我使用Moops并且我喜欢这样的工作:

use Moops;

class A {
  fun f {
    print "yay,f!\n";
  }
}

class B extends A {
  fun g {
    f();
  }
}
B->g(); # should print 'yay, f!'

相反,这会产生:

Undefined subroutine &B::f called at static-functions-lexical-scope.pl line 11.

我可以"修复"通过继承A中的ExporterB中的use语句,就像这样:

class A extends Exporter {
  our @EXPORT = qw(f);
  fun f {
    print "yay,f!\n";
  }
}

class B extends A {
  use A;
  fun g {
    f();
  }
}

这看起来有点笨拙,但如果在另一个文件中定义了A,情况会变得更糟。然后,我必须在use A之外添加第二个requireB赢了),如下所示:

use  A;
class B extends A {
  use A;
  fun g {
    f();
  }
}

有没有办法让词汇包含(导出的)功能更优雅?

1 个答案:

答案 0 :(得分:5)

首先,感谢使用Moops! : - )

其次,在测试和示例中命名类“B”可能是个坏主意。有一个名为B的模块随Perl一起提供,而Moops实际上使用它!

根据您的实际问题,一般来说,与课程相关,您应该考虑method而不是fun。方法调用尊重继承;函数调用没有。

use Moops;

class AAA {
  method f {
    say "yay,f!";
  }
}

class BBB extends AAA {
  method g {
    $self->f;
  }
}

BBB->g;

输出:

yay,f!

如果您希望AAABBB都提供便利函数库,请将这些便捷函数拆分为单独的包:

use Moops;

namespace MyUtils {
  use Exporter::Shiny qw( f );
  fun f {
    say "yay,f!";
  }
}

class AAA {
  use MyUtils -all;
  method m1 {
    f();
  }
}

class BBB extends AAA {
  use MyUtils -all;
  method m2 {
    f();
  }
}

BBB->m1;
BBB->m2;

输出:

yay,f!
yay,f!

你甚至可以更进一步,从内部扩展Moops。以下示例定义了可以添加到类的:utils特征:

use Moops;

namespace MyUtils {
  use Exporter::Shiny qw( f );
  fun f {
    say "yay,f!";
  }
}

role Moops::TraitFor::Keyword::utils {
   around generate_package_setup {
     return (
       $self->$next(@_),
       'use MyUtils -all;',
     );
   }
}

class AAA :utils {
  method m1 {
    f();
  }
}

class BBB extends AAA :utils {
  method m2 {
    f();
  }
}

BBB->m1;
BBB->m2;

与前一个示例相同的输出。