2

Moose で属性に特定の型を持たせたいが、null 値 (undef?) も許可するように指定する方法はありますか?

たとえば、Linked List の単純な実装を作成していて、nextおよびprevポインターが型である必要がある Node クラスがありますNode(これはおそらくあなたが期待するものです)。

package Node;
{
   use Moose; 

   has 'value' => (
      is  => 'rw',
      isa => 'Any', # Nodes can be of any type
   );

   has 'prev' => (
      is        => 'rw',
      isa       => 'Node',
      predicate => 'has_prev',
   );

   has 'next' => (
      is        => 'rw',
      isa       => 'Node',
      predicate => 'has_next',
   );

}

しかし、リストの実際の要素ではなく、リストの先頭に格納されているセンチネルの空のノードを使用して先頭をマークしたいと考えていました。したがって、要素 [1, 2, 3] のリストは実際には次のようになります。

EMPTY -> 1 -> 2 -> 3

nextおよびprevポインターに空の値 (undef など) を指定できるようにしたいと考えていましたNodeが、List クラスで空の値を作成すると、次のようになります。

package List;
{
   use Moose;

   has 'head' => (
      is      => 'rw',
      isa     => 'Node',
      # empty head node
      default => sub { 
         Node->new( value => undef, next => undef, prev => undef ); 
      }, 
   );

undefタイプが ではないため、Moose は文句を言いNodeます。

これを回避する方法はありますか?

4

3 に答える 3

5

Maybe[type]タイプ or を許可する構文を使用できますundef。あなたの例:

   has 'head' => (
      is      => 'rw',
      isa     => 'Maybe[Node]',
      # empty head node
      default => sub { 
         Node->new( value => undef, next => undef, prev => undef ); 
      }
   );
于 2013-07-08T18:40:28.420 に答える
1

次:

use 5.014;
use warnings;

package Node {
   use Moose; 
   has 'value' => ( is  => 'rw');
   has 'prev' => ( is => 'rw', isa => 'Undef|Node', predicate => 'has_prev', default=>undef );
   has 'next' => ( is => 'rw', isa => 'Undef|Node', predicate => 'has_next', default=>undef );
}

package List {
   use Moose;
   has 'head' => ( is => 'rw', isa => 'Node', default => sub { Node->new() } );
}

package main;
use Data::Dumper;

my $list = List->new();
say Dumper $list;

プリント:

$VAR1 = bless( {
                 'head' => bless( {
                                    'next' => undef,
                                    'prev' => undef
                                  }, 'Node' )
               }, 'List' );

Moose::Manual::Typesは、基本階層について次の ように述べています。

      Undef     <---- undefined
      Defined
          Value
              Str
                  Num
                      Int
                  ClassName <---- Class name
                  RoleName

セクションの後半で、TYPE UNIONSは次のように述べています。

Moose では、属性が 2 つ以上の異なるタイプである可能性があると言えます。たとえば、Object または FileHandle を許可する場合があります。

has 'output' => ( is => 'rw', isa => 'Object | FileHandle', );

他の人がすでに言っているように、ここにMaybe[Something]もあります。何が良いのかわかりませんが、Something | SomethingOther見た目はより「パーリッシュ」です(IMHO)。;)

于 2013-07-08T18:47:54.047 に答える
0

著者Undef|NodeMaybe[Node].

has 'prev' => (
   is        => 'rw',
   isa       => 'Undef|Node',
   predicate => 'has_prev',
);
于 2013-07-08T18:46:13.883 に答える