Can someone please explain how to implement and utilize privately-scoped arrays in Moops?

122 views Asked by At

I am trying to learn Moops and I can't quite grasp how to use populate and iterate over lexical_has arrayRefs. Can you demonstrate their usage here with code please?

I wrote the following:

lexical_has people => (is => 'rw', 
                       isa => ArrayRef, 
                       default => sub { [] }, 
                       accessor => \(my @people), 
                       required => 0);

I tried to populate it thusly:

$self->$people[$counter](Employee->new()->dispatch());

But it keeps error-ing on me "Syntax error near >$people[]"

1

There are 1 answers

1
tobyink On BEST ANSWER

You are setting accessor => \@people which shows a fundamental misunderstanding of what lexical_has does. lexical_has installs a coderef into that variable, so it ought to be a scalar.

So, once you have $people as a scalar, which lexical_has has installed a coderef into, then $self->$people() or $self->$people is a method call which returns an arrayref. Thus @{ $self->$people } is the (non-ref) array itself, which you can use for push/pop/shift/unshift/grep/map/sort/foreach/etc.

Quick example:

use Moops;

class GuestList {

  lexical_has people => (
    isa      => ArrayRef,
    default  => sub { [] },
    reader   => \(my $people),
    lazy     => 1,
  );

  method add_person (Str $name) {
    push @{ $self->$people }, $name;
  }

  method announce () {
    say for @{ $self->$people };
  }

}

my $list = GuestList->new;
$list->add_person("Alice");
$list->add_person("Bob");
$list->add_person("Carol");
$list->announce;

Output is:

Alice
Bob
Carol

Here is the equivalent code using a public attribute for people...

use Moops;

class GuestList {

  has people => (
    is       => 'ro',
    isa      => ArrayRef,
    default  => sub { [] },
    lazy     => 1,
  );

  method add_person (Str $name) {
    push @{ $self->people }, $name;
  }

  method announce () {
    say for @{ $self->people };
  }

}

my $list = GuestList->new;
$list->add_person("Alice");
$list->add_person("Bob");
$list->add_person("Carol");
$list->announce;