如何在多个 Moose 对象之间共享属性?

发布于 2024-11-26 23:19:48 字数 3138 浏览 1 评论 0原文

我需要指导。最近我已经将我的生活方式转变为驼鹿。总的来说,我发现驼鹿让生活变得更加有趣和有趣。与此同时,我仍然没有达到让我感觉更有效率的地步......可能是因为我一直在抽象中迷失自己,并且仍然没有学到足够的知识来有效地解析驼鹿文档以了解什么其他聪明人已经解决了。在驼鹿走进我的生活之前,我进行了零面向对象编程。

这是我的问题:有没有一种简单的方法可以在对象之间共享属性(相同的内存位置)?这是不好的做法吗?在下面的 AoA 示例中,我使用 AoA icol 属性来访问底层数组中我想要的内容。另一种方法是让属性 i 和 icol 引用相同的值(更改一个并更改所有)。我倾向于下面的解决方案,因为它看起来更清晰,但如果有人愿意看一下并帮助我改进我的想法,我将非常感激。另一个问题:我是否必须在 MyArray 类中设置 ents 属性的句柄?我尝试注释掉,但丢失了这些方法。

{

    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;

I am in need of guidance. I've been switching my lifestyle over to Moose as of late. Overall, I've found that moose makes life much more interesting and fun. At the same time, I still haven't gotten to a point where I feel more productive... probably because I keep losing myself in abstraction and still haven't learned enough to be able to parse the moose docs effectively enough to know what other smarter folks have solved already. I did zero OO programming before moose walked into my life.

Here's my question: Is there an easy way to share an attribute (the same memory location) between objects? Is that bad practice? In the AoA example below, I use the AoA icol attribute to access what I want in the underlying array. The other approach is to have the attribute i and and icol reference the same value (change one and change all). I'm leaning toward the solution below because it seems clearer, but I would really appreciate if anyone would give it a look and help me improve my thinking. Another question: do i have to set the handles for ents attribute in the MyArray class? I tried commenting out, and lost those methods.

{

    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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

年华零落成诗 2024-12-03 23:19:48

我想你想使用 MooseX::ClassAttribute。

I think you want to use MooseX::ClassAttribute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文