eouti
eouti

Reputation: 5658

Perl, @array in perl constructor

I write perl classes, but I don't know how to have a array or a hash in my $this variable ?

I have a pack.pm :

#!/usr/bin/perl -w
use strict;
use Parallel::ForkManager;
package Pack;

our $cgi = new CGI;

sub new {
    my ($classe, $nom, $nbports, $gio) = @_;

    my $this = {
    "nom"    => $nom,
    "nbports" => $nbports,
    "gio"   => $gio
    };

    bless($this, $classe);
    return $this;   
}
    ...
1;

I would like to have a @tab, I can access via $this->tab, but I don't want to give it in arg to the instance.
How does it work in Perl ?

Thanks.

Upvotes: 5

Views: 4062

Answers (3)

daotoad
daotoad

Reputation: 27183

Consider using Moose for your OO Perl needs.

I've created a Moose version of your object that includes an attribute with an attribute featuring Array trait delegation, inlcuding currying of delegated methods. Moose offers easy ways to generate powerful, encapsulated classes without writing reams of boilerplate.

I created a class Pack with attributes: nom, nbports, gio, and tab.

nom is a read-only string and is required when the object is created. nbports is a read-only integer value and defaults to 32 when not provided. gio is an optional, read-write boolean value. tab is an array of strings. All sorts of behavior has been defined for tab:

  • all_tabs returns a list of the contents of tabs
  • add_tab pushes values onto the end of tabs
  • tab_count returns a count of the elements in tabs
  • alpha_tabs returns a list of the members of tabs alphabetical order
  • turn_tabs returns a list of the strings in tabs, but with the letters in reverse

Any attempts to set an attribute with be checked for type correctness.

Moose creates all the required methods to support these complex behaviors with the following code:

package Pack;
use Moose;

has 'nom' => (
   is => 'ro',
   isa => 'Str',
   required => 1,
);

has 'nbports' => (
   is      => 'ro',
   isa     => 'Int',
   default => 32,
);

has 'gio' => (
   is  => 'rw',
   isa => 'Bool',
   predicate => 'has_gio',
);

has 'tab' => (
   traits  => ['Array'],
   is      => 'ro',
   isa     => 'ArrayRef[Str]',
   default => sub {[]},
   handles => {
      all_tabs    => 'elements',
      add_tab     => 'push',
      turn_tabs   => [ 'map', sub { reverse } ],
      tab_count   => 'count',
      alpha_tabs  => [ 'sort', sub { lc($a) cmp lc($b) } ],
  },
);

__PACKAGE__->meta->make_immutable;
no Moose;
1;

Usable like so:

 my $p = Pack->new( nom => 'Roger', tab => [qw( fee fie foe fum )] );

 my $gio_state = 'UNSET';
 if( $p->has_gio ) {
      $gio_state = $p->gio ? 'TRUE' : 'FALSE';
 }

 print  "GIO is $gio_state\n";

 my @turned = $p->turn_tabs; # eef eif eof muf
 $p->add_tabs( 'faa', 'fim' );
 my @sorted = $p->alpha_tabls; # faa fee fie fim foe fum

 my $count = $p->tab_count;  # 6

 my $ports = $p->nbports; # 32

Upvotes: 3

AAT
AAT

Reputation: 3386

Given your answer to my comments, I think you want

my($this) = {
    "nom"     =>  $nom,
    "nbports" =>  $nbports,
    "gio"     =>  $gio,
    "tab"     =>  []
};

i.e. set $this->{tab} to be a reference to a new anonymous array.

Now you can reference it as you wish, e.g.

$this->{"tab"}[0] = "new value";
print "Table contains ", scalar(@{$this->{"tab"}}), "entries\n";

Upvotes: 4

Tudor Constantin
Tudor Constantin

Reputation: 26861

try with:

sub set_tab {
my ($self, @tab) = @_;
$self->{ tab } = \@tab;
}

Upvotes: 2

Related Questions