Working with array references

  • Thread starter Frederik Vanderstraeten
  • Start date
F

Frederik Vanderstraeten

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.
 
P

Paul Lalli

Frederik said:
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
 
F

Frederik Vanderstraeten

Paul Lalli schreef:
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.
 
P

Paul Lalli

Frederik said:
Paul Lalli schreef:

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.
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
 
F

Frederik Vanderstraeten

Paul Lalli schreef:
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.
 
I

Ingo Menger

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.
 
X

xhoster

Frederik Vanderstraeten said:
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
 
J

John Bokma

Paul Lalli said:
Frederik Vanderstraeten wrote:

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.
 
F

Frederik Vanderstraeten

(e-mail address removed) schreef:
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.
 
F

Frederik Vanderstraeten

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?
 
F

Frederik Vanderstraeten

Jim Gibson schreef:
Frederik said:
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
 
X

xhoster

Frederik Vanderstraeten said:
(e-mail address removed) schreef:

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
 
C

cmic

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top