Как разделить атрибут между несколькими объектами Moose? - PullRequest
1 голос
/ 28 июля 2011

Мне нужно руководство.В последнее время я переключаю свой образ жизни на Лося.В целом, я обнаружил, что лоси делают жизнь намного интереснее и веселее.В то же время, я до сих пор не дошел до точки, где я чувствую себя более продуктивно ... возможно, потому что я продолжаю терять себя в абстракции и все еще не научился достаточно, чтобы иметь возможность достаточно эффективно анализировать документы лося, чтобы знать, чтодругие умные люди уже решили.Я сделал нулевое ОО-программирование до того, как лось вошел в мою жизнь.

Вот мой вопрос: есть ли простой способ поделиться атрибутом (тем же местом в памяти) между объектами?Это плохая практика?В приведенном ниже примере AoA я использую атрибут ico AoA для доступа к тому, что я хочу в базовом массиве.Другой подход заключается в том, чтобы атрибуты i и icol ссылались на одно и то же значение (измените одно и измените все).Я склоняюсь к решению ниже, потому что оно кажется более ясным, но я был бы очень признателен, если бы кто-нибудь взглянул на это и помог мне улучшить мое мышление.Другой вопрос: мне нужно установить дескрипторы для атрибута ents в классе MyArray?Я попытался закомментировать и потерял эти методы.

{

    package AoA;
    use namespace::autoclean;
    use Moose;

    has [qw(icol irow)] => (
        is      => 'rw',
        isa     => 'Int',
        default => 0,
    );

    has 'rows' => (
        traits  => ['Array'],
        is      => 'rw',
        isa     => 'ArrayRef',
        default => sub { [] },
        handles => {
            add_row   => 'push',
            get_row   => 'get',
            set_row   => 'set',
            all_rows  => 'elements',
          count_rows  => 'count',
        },
    );


    sub get_element {
      my $self = shift;
      @_ == 2 ?
        return $self->get_row($_[0])->get($_[1]) :
        return $self->get_row($self->irow)->get($self->icol);
    }

    sub add_col {
      my $self=shift;
      my $nrows = $self->count_rows-1;
      foreach my $i (0 .. $nrows){
        $_[$i] ?  $self->rows->[$i]->push($_[$i]) : $self->rows->[$i]->push(undef);
      }
    }

    sub get_col {
      my $self = shift;
      my $icol = shift || $self->icol;
      my $nrows = $self->count_rows-1;
      my @column;

      foreach (0 .. $nrows){
        my $row = $self->get_row($_); 
        $icol <= $row->count ? push @column, $row->get($icol): push @column, undef;
      }
      return \@column;
    }

    __PACKAGE__->meta->make_immutable;
}

{
    package MyArray;
    use namespace::autoclean;
    use Moose;

    has 'i' => (
        is      => 'rw',
        isa     => 'Int',
        default => 0,
    );

    has 'ents' => (
        traits  => ['Array'],
        is      => 'rw',
        isa     => 'ArrayRef',
        default => sub { [] },
        handles => {
            push      => 'push',
            get       => 'get',
            set       => 'set',
            elements  => 'elements',
            count     => 'count',
        },
    );

    __PACKAGE__->meta->make_immutable;

}

use Modern::Perl;

my $a0 = MyArray->new( ents => [ 0, [ 0, 0, 0 ], [1,2,3] ] ) ;
my $a1 = MyArray->new( ents => [ 1, [ 1, 1, 1 ], [4,5,6] ] ) ;
my $a2 = MyArray->new( ents => [ 2, [ 2, 2, 2 ], [7,8,9] ] ) ;

my $a = AoA->new( rows => [ $a0, $a1] )  ;

$a->add_row($a2);
$a->add_col([3,3,3],[4,4,4],[5,5,5]);

my $row0        = $a->get_row(0);
my $row1        = $a->get_row(1);
my $row2        = $a->get_row(2);

my $element_22   = $a->get_element(2,2);

my $col2        = $a->get_col(1);

use Data::Dumper;

print Dumper $row0;
print Dumper $row1;
print Dumper $row2;
print Dumper $col2;
print Dumper $element_22;

$a0->set(0,'cat');
print Dumper $row0;


1;

1 Ответ

3 голосов
/ 28 июля 2011

Я думаю, вы хотите использовать MooseX :: ClassAttribute .

...