一个perl6模块可以有条件地“使用”另一个perl6模块吗?

时间:2019-01-06 17:44:57

标签: perl6

是否有一种明智的方法来让一个perl6模块检查是否存在另一个perl6模块,并且仅当已安装时才“使用”它?

像这样...

module Polygons;

if $available {
    use Measure;                #only if Measure is installed
}

class Rectangle is export {
    has $.width;
    has $.height;

    method area {
        $!width * $!height;     #provides operator overload for Measure * Measure
    }
}
#====================

module Measure;

class Measure is export {
    has $.value;
    has $.unit;

    method Real {
        $!value;
    }
    method Str {
        "$!value $!unit";
    }
    method multiply( $argument ) {
        my $result = $.;
        $result.value = $!value * $argument;
        $result.unit  = "$!unit2";
        return $result;
    }
}

multi infix:<*> ( Measure:D $left, Measure:D $right ) is export {
    return $result.multiply( $argument );
}

#====================

#main.p6

use Polygons;
use Measure;

my $x = Measure.new( value => 10, unit => 'm' );
my $y = Measure.new( value => 20, unit => 'm' );

my $rect = Rectangle.new( width => $x, height => y );
say $rect.area;        #'200 m2'

想法是将运算符重载(在本例中为infix:<*>)传播回类继承,以便在属性中存储更多复杂的对象。

(请不要撕裂下水道,因为我怀疑总有办法!)

1 个答案:

答案 0 :(得分:4)

因此,该答案的第一个版本基本上没有用。

这是我想出的第一个新东西,可以理解您的问题。我还没有在仓库中尝试过它。

在文件a-module.pm6中:

unit module a-module;
our sub infix:<*> ($l,$r) { $l + $r } }

our意味着我们可以require看到此例程,尽管只能通过其完全限定的名称&a-module::infix:<*>看到它。

然后在使用文件中:

use lib '.';
try require a-module;
my &infix:<*> = &a-module::infix:<*> // &OUTER::infix:<*>;
say 1 * 2 # 2 or 3 depending on whether `a-module.pm6` is found

如果缺少该模块,则使用的默认例程可以是OUTER(如图所示)中的例程,也可以是CALLER或您喜欢的任何其他pseudo package中的例程。

这个问题/解决方案似乎太基本了,我怀疑它一定在SO上或文档中的某个地方。我将发布我所拥有的,然后明天再进行探索。