Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Storing arrays as object variables

by Basilides (Friar)
on Jul 20, 2002 at 14:25 UTC ( [id://183595]=perlquestion: print w/replies, xml ) Need Help??

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

Object variables in perl seem to be stored as hash elements, so you refer to them like $self->{_foo}.

Because hashes can only hold scalar values, if I want my object to have an array as one of it's attributes, I guess I create the array, and store a reference to it in the object's hash:

my @array; $self->{_array} = \@array;
I have to say, this seems to work, but just thinking about it last night I had a bit of a panic, because it seems that, while the reference belongs to the object and therefore won't go changing, the actual array itself is only scoped in this particular section of code, so maybe I can't be sure if it'll behave as expected way later in the program when I come back and derefence my pointer.

Could someone either set my mind at rest, or tell me the right way to store arrays (or hashes) in an object.

Replies are listed 'Best First'.
(jeffa) Re: Storing arrays as object variables
by jeffa (Bishop) on Jul 20, 2002 at 15:29 UTC
    "Object variables in perl seem to be stored as hash elements..."

    Only if the object in question is a blessed hash reference. A Perl object is simply a blessed referent - you can also bless arrays, subroutines, regexes, and even scalars. See Blessables -- What Can You Make Into Objects? for more on that.

    Back to your array ref - meditate on the following code: a class is defined with a single attribute (an array ref) and two accessor methods - one that returns a copy of the array ref and one that returns a copy of the array. Various methods of trying to change the attribute are attempted, but the only one that works is the last one, which assigns a new array ref explicitly.
    use strict; my (@array,$array); my $foo = foo->new(); # won't change @array = $foo->get_array; @array = ('a'..'f'); print join(',',$foo->get_array),"\n"; # won't change $array = $foo->get_array_ref; $array = [('a'..'f')]; print join(',',$foo->get_array),"\n"; # won't change $array = $foo->{_array}; $array = [('a'..'f')]; print join(',',$foo->get_array),"\n"; # will change $foo->{_array} = [('a'..'f')]; print join(',',$foo->get_array),"\n"; package foo; use strict; sub new { bless { _array => [(0..9)] }, shift } sub get_array { @{shift->{_array}} } sub get_array_ref { shift->{_array} }
    And please note that i 'abbreviated' this object's methods only for the sake of brevity. Please don't use this style in production code. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Storing arrays as object variables
by Courage (Parson) on Jul 20, 2002 at 14:48 UTC
    Don't panic, your piece of code would work correctly. That array is not seen outside it's scope, but still exists, as long as "my" created it into existence!

    Also you could write your code as

    $self->{_array} = ['your','array','elements',@go,'here'];

    Courage, the Cowardly Dog.

Re: Storing arrays as object variables
by chromatic (Archbishop) on Jul 20, 2002 at 15:23 UTC

    Perl uses a reference-counting garbage collection scheme. Declaring the lexical increments the reference counter to one, and storing a reference in the object increments the counter to two. When the @array name goes out of scope, the counter is decremented back to one. Since the object still holds a reference, the actual array data structure will not be garbage collected.

      I always like to give a code example. This is a simple demonstration of how data sticks arround even though the original @array is out of scope. You rarely have to worry about losing data when it goes out of scope. You really have to watch for memory leaks when you create circular references. Read perlreftut and perlref for more info.
      use strict; my $arrayref; { #create a closure for @array my @array = qw(zero one two three); $arrayref = \@array; } # @array is out of scope but @array's data still there print $arrayref->[1],"\n"; # prints "one" $arrayref->[4] = $arrayref; # circular reference. $arrayref = 1; # memory leak ! # @array's memory is never freed # until program ends!

      --

      flounder

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://183595]
Approved by Courage
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-25 12:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found