use Moops;
# Moops + multidimensional TypedArray example courtesy of TOBYINK:
# http://www.perlmonks.org/?node_id=1052124
class Cell {
has name => (is => 'rw', isa => Str);
}
class Grid types Types::Standard, List::Objects::Types {
my $CellType = (InstanceOf['Cell'])->plus_coercions(
Str, sub { 'Cell'->new(name => $_) },
);
has cells => (
is => 'ro',
isa => TypedArray[TypedArray[$CellType]],
coerce => 1,
handles => {
get_row => 'get',
set_row => 'set',
all_rows => 'all',
add_row => 'push',
},
);
method get_cell (Int $row, Int $col) {
$self->get_row($row)->get($col);
}
method set_cell (Int $row, Int $col, Str|Object $value) {
$self->get_row($row)->set($col, $value);
}
method all_cells () {
map { $_->all } $self->all_rows;
}
method get_col (Int $col) {
map { $_->get($col) } $self->all_rows;
}
method set_col (Int $col, ArrayRef|ArrayObj $values) {
my @rows = $self->all_rows;
for my $i (0 .. $#rows) {
$rows[$i]->set($col) = $values->[$i];
}
}
method add_col (ArrayRef|ArrayObj $values) {
my @rows = $self->all_rows;
for my $i (0 .. $#rows) {
$rows[$i]->push($values->[$i]);
}
}
method all_cols () {
my $col_count = $self->get_row(0)->count;
my $return_type = TypedArray[$CellType];
return
map { $return_type->coerce($_); }
map { [ $self->get_col($_) ]; }
0 .. $col_count-1;
}
method to_string () {
join "\n", map(join("\t", map($_->name, $_->all)), $self->all_rows);
}
}
my $grid = Grid->new(
cells => [
[ 'foo1', 'bar1' ],
[ 'foo2', 'bar2' ],
]
);
$grid->add_col(['baz1', 'baz2']);
$grid->get_cell(1, 1)->name('QUUX');
say $grid->to_string;