Hosen1989 has asked for the wisdom of the Perl Monks concerning the following question:

defined class variable with Moose

Dear ALL,

I need to add array of data to my class (using Moose) and be able to read it inside me class, I thinks something like this:

here I many use different @parserArray_type_xx with each different file depend on its type to parse it.

so my Q is: How to do it?

<pEdit:###############################

As my question here was not clear,let me ask again: but what i need to do is to define variable in my class that contain some predefined data (mix of array/hash/scalar/code).

BR

Hosen

package DataDecoder; use Moose; ... #######need to add something like this####### my @parserArray_type_01 = ( ... { name => 'YEAR', type => 'CHAR', len => 2, description => sub{0} }, { name => 'MONTH', type => 'CHAR', len => 2, description => sub{0} }, { name => 'DAY', type => 'CHAR', len => 2, description => sub{0} }, { name => 'HOUR', type => 'CHAR', len => 2, description => sub{0} }, { name => sub{ my $data = uc shift; my %SUD_DATA = ('98' => 'TYPE1', '64' => 'TYPE2'); ); (defined $SUD_DATA{$data})? $SUD_DATA{$data} : $data # $data }, type => 'HEX', len => 1, description => sub{ my $data = uc shift; my %SUD_DATA = ('98' => 'TYPE1', '64' => 'TYPE2'); (defined $SUD_DATA{$data})? $SUD_DATA{$data} : $data # $data }, } ); ...

Replies are listed 'Best First'.
Re: defined class variable with Moose
by kcott (Archbishop) on Jun 26, 2015 at 19:01 UTC

    G'day Hosen1989,

    I suspect you may be mixing (and consequently, confusing) this type of Moose syntax:

    has attribute => ( default => sub { 0 }, );

    with normal Perl syntax for creating key-value pairs:

    { default => 0, }

    sub { 0 } is a code reference.

    For your simpler cases, like

    description => sub{0}

    you could just use

    description => 0

    However, regardless of the complexity of the code within sub { ... }, what you really want is the return value when that code is executed. For that, use

    sub { ... }->()

    Consider these three one-liners:

    $ perl -wE 'my $x = { y => 0 }; say $x->{y}' 0
    $ perl -wE 'my $x = { y => sub { 0 } }; say $x->{y}' CODE(0x7f8c34026a60)
    $ perl -wE 'my $x = { y => sub { 0 }->() }; say $x->{y}' 0

    -- Ken

      Hi there,

      Thanks for you reply.

      I can see that my code hare are somewhat confusing, but I use description => sub{0} in-stand of description => 0 to keep the consist with other item in my @parserArray, as i need them to be in the same format where i use each item in this array to read some part of my raw file.

      As my question here was not clear,let me ask again: but what i need to do is to define variable in my class that contain some predefined data (mix of array/hash/scalar/code).

      BR

      Hosen

        "but I use description => sub{0} in-stand of description => 0 to keep the consist with other item in my @parserArray, ..."

        I only said "you could just use", not "you must use". That was just a suggestion. By all means, keep them consistent.

        The main thrust of what I was pointing out, was that a value of 'sub { 0 }->()', or just a plain old '0', will evaluate to 0; however, the 'sub { 0 }' that you showed evaluates to something like CODE(0x7f8c34026a60).

        "... what i need to do is to define variable in my class that contain some predefined data"

        Isn't @parserArray_type_01 just such a variable with predefined data?

        I don't see a reason why you can't use something like $parserArray_type_01[$index]{$key} in your code (whether it uses Moose or not).

        Please post a short piece of code (10-20 lines) that demonstrates where such a variable is causing problems.

        -- Ken

Re: defined class variable with Moose
by kevbot (Vicar) on Jun 27, 2015 at 04:36 UTC

    I'm not sure I completely understand your question, but do you just want an attribute that contains your data structure? If so, you can do something like this...

    In DataDecoder.pm,
    package DataDecoder; use Moose; has 'parserArray_type_01_ref' => ( is => 'ro', isa => 'ArrayRef', builder => 'get_type_01_ref', lazy => 1 ); sub get_type_01_ref { my $array_ref = [ { name => 'YEAR', type => 'CHAR', len => 2, description => sub{0} }, { name => 'MONTH', type => 'CHAR', len => 2, description => sub{0} }, { name => 'DAY', type => 'CHAR', len => 2, description => sub{0} }, { name => 'HOUR', type => 'CHAR', len => 2, description => sub{0} }, { name => sub{ my $data = uc shift; my %SUD_DATA = ('98' => 'TYPE1', '64' => 'TYPE2'); (defined $SUD_DATA{$data})? $SUD_DATA{$data} : $data # $data }, type => 'HEX', len => 1, description => sub{ my $data = uc shift; my %SUD_DATA = ('98' => 'TYPE1', '64' => 'TYPE2'); (defined $SUD_DATA{$data})? $SUD_DATA{$data} : $data # $data }, } ]; return $array_ref; } 1;
    In test.pl,
    #!/usr/bin/env perl use DataDecoder; my $dd = DataDecoder->new(); my @array = @{$dd->parserArray_type_01_ref}; use Data::Dumper; print Dumper @array; exit;
    If you run test.pl you should see a dump of your data structure.

    Take a look at Moose::Manual::Attributes and Moose::Manual::BestPracties for more information.