Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl Moose Hash Accessors

Tags:

hash

perl

I am trying the Moose example:

has 'options' => (
      traits    => ['Hash'],
      is        => 'rw',
      isa       => 'HashRef[Str]',
      default   => sub { {} },
      handles   => {
          set_option     => 'set',
          get_option     => 'get',
          has_no_options => 'is_empty',
          num_options    => 'count',
          delete_option  => 'delete',
          option_pairs   => 'kv',
      },
  );

and I found it works like this:

$self->set_option("step1", "Step 1");
printf ("Get option %s\n", $self->get_option("step1"));

but I thought if I remove the handles I could access the hash elements like this:

$self->options->set("step1", "Step 1");
printf ("Get option %s\n", $self->options->get("step1"));

I need to have many hashes in the same class, how to access each hash with accessors like:

$self->hash1->get("key1");
$self->hash2->get("key1");
like image 466
daliaessam Avatar asked Mar 01 '14 20:03

daliaessam


1 Answers

No, you can't do:

$self->options->set("step1", "Step 1");
printf ("Get option %s\n", $self->options->get("step1"));

... because $self->options just returns a plain hashref, not an object. You can't call methods on a plain hashref. (Well, there's always autobox.)

But just because you're using Moose, don't forget that you're also using Perl. And in Perl you don't need methods to access a hashref. It's a hashref. You can just get and set keys like any other hashref:

$self->options->{"step1"} = "Step 1";
printf ("Get option %s\n", $self->options->{"step1"});

If you really, really love the syntax:

$self->options->set("step1", "Step 1");
printf ("Get option %s\n", $self->options->get("step1"));

Then the solution is the aforementioned autobox, or to not use hashrefs, but instead use a objects that offer get/set methods. For example List::Objects::WithUtils. Here's a quick example:

use v5.10;
use strict;
use warnings;

{
   package Foo;

   use Moose;
   use List::Objects::Types qw( HashObj );

   has options => (
      is      => 'ro',
      isa     => HashObj,
      coerce  => 1,
      default => sub { {} },
   );
}

my $obj = Foo->new;

$obj->options->set("step1", "Step 1");
printf("Get option %s\n", $obj->options->get("step1"));
like image 169
tobyink Avatar answered Oct 10 '22 20:10

tobyink