3

私は使用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.

Exporterinから継承し、次のようなAステートメントuseを使用することで、これを「修正」できます。B

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

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

Aこれは少し扱いに​​くいように見えますが、 が別のファイルで定義されている場合はさらに悪化します。次に、次のように外に2番目を追加する必要がありますuse Arequireしません) :B

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

(エクスポートされた) レキシカル インクルージョン関数をよりエレガントに動作させる方法はありますか?

4

1 に答える 1

5

まず、Moops をご利用いただきありがとうございます。:-)

第二に、テストや例でクラス「B」に名前を付けるのはおそらく悪い考えです。Perl に付属しているというモジュールがありB、Moops は実際にそれを使用しています。

methodあなたの実際の質問に来て、一般的にクラスについて言えば、.ではなく考えるべきですfun. メソッド呼び出しは継承を尊重します。関数呼び出しはしません。

use Moops;

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

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

BBB->g;

出力:

yay,f!

AAA便利な関数のライブラリを両方で利用できるようにする場合はBBB、これらの便利な関数を別のパッケージに分割します。

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;

前の例と同じ出力。

于 2014-08-28T19:32:52.983 に答える