Working with array references

Discussion in 'Perl Misc' started by Frederik Vanderstraeten, Jan 10, 2007.

  1. Hi

    I'm new to Perl. I have a question about array references: what's the
    best way to use them? How do I add an element, remove an element, ... Is
    dereferencing the best way?
    E.g., what is the easiest way to rewrite this:

    $arrayRef = $obj->get('myArray');
    @array = $@arrayRef;
    @array = (@array, 'newElement');
    $obj->set('myArray', \@array);

    As get returns a reference, I assume I could easily do all of this in
    one statement.
     
    Frederik Vanderstraeten, Jan 10, 2007
    #1
    1. Advertising

  2. Frederik Vanderstraeten

    Paul Lalli Guest

    Frederik Vanderstraeten wrote:
    > Hi
    >
    > I'm new to Perl. I have a question about array references: what's the
    > best way to use them? How do I add an element, remove an element, ... Is
    > dereferencing the best way?
    > E.g., what is the easiest way to rewrite this:
    >
    > $arrayRef = $obj->get('myArray');
    > @array = $@arrayRef;
    > @array = (@array, 'newElement');
    > $obj->set('myArray', \@array);
    >
    > As get returns a reference, I assume I could easily do all of this in
    > one statement.


    Not only is that a syntax error, that's also the worst possible way to
    access an array by its reference. You're making three separate copies
    of the array, for no reason of any kind.

    If you have $arrayRef, you get the array that $arrayRef references by
    surrounding it in @{...}. From there, you can use that array like you
    would any other array:

    $arrayRef = $obj->get('myArray');
    push @{$arrayRef}, 'newElement';
    $obj->set('myArray', $arrayRef);

    You need to read a decent tutorial on references:
    perldoc perlreftut

    Paul Lalli
     
    Paul Lalli, Jan 10, 2007
    #2
    1. Advertising

  3. Paul Lalli schreef:
    > Frederik Vanderstraeten wrote:
    >> Hi
    >>
    >> I'm new to Perl. I have a question about array references: what's the
    >> best way to use them? How do I add an element, remove an element, ... Is
    >> dereferencing the best way?
    >> E.g., what is the easiest way to rewrite this:
    >>
    >> $arrayRef = $obj->get('myArray');
    >> @array = $@arrayRef;
    >> @array = (@array, 'newElement');
    >> $obj->set('myArray', \@array);
    >>
    >> As get returns a reference, I assume I could easily do all of this in
    >> one statement.

    >
    > Not only is that a syntax error, that's also the worst possible way to
    > access an array by its reference. You're making three separate copies
    > of the array, for no reason of any kind.


    Sorry, I didn't test that code. I wasn't going to use something as ugly
    as that anyway.
    I know it's a bad way, that's why I'm asking for a better one. :)

    > If you have $arrayRef, you get the array that $arrayRef references by
    > surrounding it in @{...}. From there, you can use that array like you
    > would any other array:
    >
    > $arrayRef = $obj->get('myArray');
    > push @{$arrayRef}, 'newElement';
    > $obj->set('myArray', $arrayRef);


    Thanks.
    So if the object actually returns a reference to that array, and not a
    reference to a copy, I wouldn't even need the set function, right?

    push @{$obj->get('myArray')}, 'newElement';

    Please correct me if this is as silly as my first code.

    > You need to read a decent tutorial on references:
    > perldoc perlreftut


    Thanks again, I read perlref but didn't understand most of it.
    This tutorial is much easier to follow.
     
    Frederik Vanderstraeten, Jan 10, 2007
    #3
  4. Frederik Vanderstraeten

    Paul Lalli Guest

    Frederik Vanderstraeten wrote:
    > Paul Lalli schreef:
    > > Frederik Vanderstraeten wrote:
    > >> $arrayRef = $obj->get('myArray');
    > >> @array = $@arrayRef;
    > >> @array = (@array, 'newElement');
    > >> $obj->set('myArray', \@array);


    > > Not only is that a syntax error, that's also the worst possible way to
    > > access an array by its reference. You're making three separate copies
    > > of the array, for no reason of any kind.

    >
    > Sorry, I didn't test that code.


    Please don't do that. You waste everyone's time by making us guess as
    to what your real code is that you're actually asking about. Please
    read the Posting Guidelines that are posted here twice a week.

    > > If you have $arrayRef, you get the array that $arrayRef references by
    > > surrounding it in @{...}. From there, you can use that array like you
    > > would any other array:
    > >
    > > $arrayRef = $obj->get('myArray');
    > > push @{$arrayRef}, 'newElement';
    > > $obj->set('myArray', $arrayRef);


    > So if the object actually returns a reference to that array, and not a
    > reference to a copy, I wouldn't even need the set function, right?
    >
    > push @{$obj->get('myArray')}, 'newElement';


    That's correct.


    Paul Lalli
     
    Paul Lalli, Jan 10, 2007
    #4
  5. Paul Lalli schreef:
    > Frederik Vanderstraeten wrote:
    >> Sorry, I didn't test that code.

    >
    > Please don't do that. You waste everyone's time by making us guess as
    > to what your real code is that you're actually asking about. Please
    > read the Posting Guidelines that are posted here twice a week.


    Sorry, and thanks for the help.
     
    Frederik Vanderstraeten, Jan 10, 2007
    #5
  6. Frederik Vanderstraeten

    Ingo Menger Guest

    Frederik Vanderstraeten schrieb:


    >
    > Thanks.
    > So if the object actually returns a reference to that array, and not a
    > reference to a copy, I wouldn't even need the set function, right?
    >
    > push @{$obj->get('myArray')}, 'newElement';
    >
    > Please correct me if this is as silly as my first code.


    This is okay syntactically, but might not be a good idea.
    The reason is that you don't know (or at least, are not supposed to
    know) what goes on inside $obj. The get-method may, for instance,
    somehow compute it's return value and in that case your push will be
    performed and then the whole array will be garbage collected.
     
    Ingo Menger, Jan 10, 2007
    #6
  7. Frederik Vanderstraeten

    Guest

    Frederik Vanderstraeten <> wrote:
    > Hi
    >
    > I'm new to Perl. I have a question about array references: what's the
    > best way to use them? How do I add an element, remove an element, ... Is
    > dereferencing the best way?
    > E.g., what is the easiest way to rewrite this:
    >
    > $arrayRef = $obj->get('myArray');
    > @array = $@arrayRef;
    > @array = (@array, 'newElement');
    > $obj->set('myArray', \@array);
    >
    > As get returns a reference, I assume I could easily do all of this in
    > one statement.


    I think the right way is for $obj to provide a "push" method for you to
    use. Otherwise, what is the point of using encapsulation?

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Jan 10, 2007
    #7
  8. Frederik Vanderstraeten

    John Bokma Guest

    "Paul Lalli" <> wrote:

    > Frederik Vanderstraeten wrote:


    >> So if the object actually returns a reference to that array, and not a
    >> reference to a copy, I wouldn't even need the set function, right?
    >>
    >> push @{$obj->get('myArray')}, 'newElement';

    >
    > That's correct.


    Unless for some reason get returns a reference to a copy of the internal
    array. This is something that *should* be documented IMO though.

    --
    John Experienced Perl programmer: http://castleamber.com/

    Perl help, tutorials, and examples: http://johnbokma.com/perl/
     
    John Bokma, Jan 10, 2007
    #8
  9. Frederik Vanderstraeten

    Paul Lalli Guest

    John Bokma wrote:

    > > Frederik Vanderstraeten wrote:

    >
    > >> [...] if the object actually returns a reference to that array, and not a
    > >> reference to a copy [....]


    > Unless for some reason get returns a reference to a copy of the internal
    > array.


    echo...echo....echo....

    Paul Lalli
     
    Paul Lalli, Jan 10, 2007
    #9
  10. schreef:
    > Frederik Vanderstraeten <> wrote:
    >> Hi
    >>
    >> I'm new to Perl. I have a question about array references: what's the
    >> best way to use them? How do I add an element, remove an element, ... Is
    >> dereferencing the best way?
    >> E.g., what is the easiest way to rewrite this:
    >>
    >> $arrayRef = $obj->get('myArray');
    >> @array = $@arrayRef;
    >> @array = (@array, 'newElement');
    >> $obj->set('myArray', \@array);
    >>
    >> As get returns a reference, I assume I could easily do all of this in
    >> one statement.

    >
    > I think the right way is for $obj to provide a "push" method for you to
    > use. Otherwise, what is the point of using encapsulation?
    >
    > Xho
    >


    It's a session object. (CGI::Session. This in fact uses param() for both
    get and set but this is only example code and it's easier to understand
    with get and set IMHO.) It is not specifically designed to store arrays.
     
    Frederik Vanderstraeten, Jan 10, 2007
    #10
  11. Frederik Vanderstraeten

    John Bokma Guest

    "Paul Lalli" <> wrote:

    > John Bokma wrote:
    >
    >> > Frederik Vanderstraeten wrote:

    >>
    >> >> [...] if the object actually returns a reference to that array,
    >> >> and not a reference to a copy [....]

    >
    >> Unless for some reason get returns a reference to a copy of the
    >> internal array.

    >
    > echo...echo....echo....


    So much for pretending to be awake :-D.

    --
    John Experienced Perl programmer: http://castleamber.com/

    Perl help, tutorials, and examples: http://johnbokma.com/perl/
     
    John Bokma, Jan 10, 2007
    #11
  12. One more question: What's the best way to make an array reference of an
    existing array? perlreftut uses [@array], is it better than \@array?
     
    Frederik Vanderstraeten, Jan 10, 2007
    #12
  13. Jim Gibson schreef:
    > In article <q7cph.283821$%-ops.be>, Frederik
    > Vanderstraeten <> wrote:
    >
    >> One more question: What's the best way to make an array reference of an
    >> existing array? perlreftut uses [@array], is it better than \@array?

    >
    > [@array] creates a copy of the array as an anonymous array and returns
    > a reference to that anonymous array.
    >
    > \@array returns a reference to the existing array


    Thanks
     
    Frederik Vanderstraeten, Jan 10, 2007
    #13
  14. Frederik Vanderstraeten

    Guest

    Frederik Vanderstraeten <> wrote:
    > schreef:
    > > Frederik Vanderstraeten <> wrote:
    > >> Hi
    > >>
    > >> I'm new to Perl. I have a question about array references: what's the
    > >> best way to use them? How do I add an element, remove an element, ...
    > >> Is dereferencing the best way?
    > >> E.g., what is the easiest way to rewrite this:
    > >>
    > >> $arrayRef = $obj->get('myArray');
    > >> @array = $@arrayRef;
    > >> @array = (@array, 'newElement');
    > >> $obj->set('myArray', \@array);
    > >>
    > >> As get returns a reference, I assume I could easily do all of this in
    > >> one statement.

    > >
    > > I think the right way is for $obj to provide a "push" method for you to
    > > use. Otherwise, what is the point of using encapsulation?
    > >
    > > Xho
    > >

    >
    > It's a session object. (CGI::Session. This in fact uses param() for both
    > get and set but this is only example code and it's easier to understand
    > with get and set IMHO.) It is not specifically designed to store arrays.


    From the source of CGI::Session, It looks like you can't just do this:

    push @{$cgi_ses->param("name")}, "foo";

    Because that would bypass the _set_status(STATUS_MODIFIED) and lead to
    potential flushing problems. This probably should be better documented by
    CGI::Session.

    So the safest thing to do would be like what you did above, make a copy
    of the referenced array, modify the copy, and store. I'd do it more
    compactly:

    $arrayRef = $obj->param('myArray');
    $obj->param('myArray', [@$arrayRef,'new_element']);

    Or even:

    $obj->param('myArray', [@{$obj->param('myArray')},'new_element']);

    In both cases, the param has to already exist and already be an arrayref.


    But if I had to do a lot of this, I would just subclass CGI::Session and
    add a "push" method to it. (Actually, I'd probably just add a push method
    directly to CGI::Session without subclassing, but I'm ashamed to admit
    that in public.)

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Jan 11, 2007
    #14
  15. Frederik Vanderstraeten

    cmic Guest

    Frederik Vanderstraeten a écrit :
    > Hi
    >
    > I'm new to Perl. I have a question about array references: what's the


    I'm a bit new, too...:cool:

    ....

    > E.g., what is the easiest way to rewrite this:
    >
    > $arrayRef = $obj->get('myArray');
    > @array = $@arrayRef;
    > @array = (@array, 'newElement');
    > $obj->set('myArray', \@array);
    >
    > As get returns a reference, I assume I could easily do all of this in
    > one statement.


    May be it is too late, but R.L.Schwartz has an article about "Show me
    your references" that might help learning references .... It is in
    SysAdmin magazine, January issue :

    http://www.samag.com/documents/s=10108/sam0701h/0701h.htm

    --
    Michel Marcon aka cmic
     
    cmic, Jan 11, 2007
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roger Leigh
    Replies:
    8
    Views:
    467
    Karl Heinz Buchegger
    Nov 17, 2003
  2. Replies:
    3
    Views:
    475
    Victor Bazarov
    Nov 10, 2004
  3. DanielEKFA
    Replies:
    8
    Views:
    631
    DanielEKFA
    May 16, 2005
  4. Replies:
    8
    Views:
    745
    Bruno Desthuilliers
    Dec 12, 2006
  5. Lars Willich
    Replies:
    13
    Views:
    890
    Ian Shef
    Oct 23, 2007
Loading...

Share This Page