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

Hi guys,
I have a problem. Ok, it's trivial, but I really do need a hand since my blind tries are not working.
I'm using OO perl; everything is running smoothly using scalars, but I have troubles using vectors.
# constructor sub new { my $this = {}; # object properties $this->{colour} = 'yellow'; sub getColour { { my $this = shift; return $this->{colour}; } sub setColour{ my $this = shift; $this->{colour} = shift; return $this->{colour}; }
And this class works. But what if I want to pass and get not just a scalar, but an array instead? I can do it easly with subroutines in structured perl, but I don't know how to do it in OO perl. For example, if I use:
$this->{colour} = ('yellow', 'red', 'purple');
When I use:
print $this->{colour};
the output is not the whole array. And I need the whole array as output...

Replies are listed 'Best First'.
Re: array as attributes in OO perl
by gwadej (Chaplain) on Nov 18, 2008 at 14:25 UTC

    You actually need a reference to an array. Try

    $this->{colour} = [ 'yellow', 'red', 'purple' ]; print "@{$this->{colour}}";

    You will, of course, need to adjust where you are using this property to dereference the reference, like I show above.

    G. Wade
Re: array as attributes in OO perl
by Fletch (Bishop) on Nov 18, 2008 at 14:39 UTC
      Actually the method suggested is working pretty good... but for sure I'll have a look also at the documents you suggested.
      Thank you guys.
Re: array as attributes in OO perl
by TGI (Parson) on Nov 18, 2008 at 19:04 UTC

    If you find yourself doing lots of "classical" Perl OO (with blessed hashes or arrays), you may want to take a look at Class::Struct. It provides a simple, but somewhat limited, way of producing your attribute methods. The nice things about Class::Struct are: it is a core module, and it is easy to understand.

    If you really want to do OO with all the goodies, all the cool kids are using Moose. I haven't tried it in a project myself, but many people who I respect are using it with good success.

    You can easily check to see if an argument is supplied to your setter methods:

    use Carp qw(croak); sub set_colour { my $this = shift croak 'set_colour requires an argument' unless @_; $this->{colour} = shift; } # if you like combined setter/getters use Scalar::Util qw(reftype); sub colour { my $this = shift; if ( @_ ) { my $arg = shift; croak 'Illegal value for method colour' unless reftype $arg eq 'ARRAY'; $this->{colour} = $arg; } return @{ $this->{colour}||[] }; }

    Some people prefer 'duck-typing' to checking reftype of a value. The basic idea is that if it quacks, it's a duck. So, to test if something is an array, we try treating it like one. If it works, then it's an array (even if it's really a tied hash behind the scenes).

    sub colour { my $this = shift; if ( @_ ) { my $arg = shift; local $@; croak 'Illegal value for method colour' unless eval { @$arg; 1 }; $this->{colour} = $arg; } return @{ $this->{colour}||[] }; }


    TGI says moo

      Oh guys, thanks a lot!
      I'm looking at Class::Struct... well, it seems to be understandable :) and furthermore I can use it to solve another problem I have here...

        I'm glad to help.

        An undocumented Class::Struct trick I learned by reading the source, is to call Class::Struct::printem(1);. You can now see the generated code.

        Definitely take the time to really grok the references documentation others have pointed you to. Mastering this material is key to moving to the next level.

        Happy hacking.


        TGI says moo

Re: array as attributes in OO perl
by mr_mischief (Monsignor) on Nov 18, 2008 at 18:52 UTC
    How would you handle this without OO? Would you assign to an array on the left, like this?:
    @colour = ('yellow', 'red', 'purple');
    If so, you can still do that using a reference.
    @{ $this->{colour} } = ('yellow', 'red', 'purple');
    Then you'd return $this->{colour} just like before, and it'd be an array reference just like in the other solutions.

    You can therefore think of the same thing two different ways. The other examples show the assignment of a reference to an anonymous array. The above might be said to be assigning to the array to which the scalar $this->{colour} refers. The ordering of the thoughts is different and the syntax is different. Yet the result is the same.

    When I first started messing with references years ago, the version with @{ $scalar } on the left seemed simpler to grasp. That notation does not scale as nicely to more complex data structures as using the anonymous reference notations on the right of the assignment operator, though.

    I personally find the array ref on the right as gwadej shows and Fletch mentions to be easier to read and less cluttered. You should definitely get used to stating things in that form, even if the one I presented helps you make the transition.