944,110 Members | Top Members by Rank

Ad:
  • Perl Discussion Thread
  • Unsolved
  • Views: 3293
  • Perl RSS
Oct 8th, 2006
0

How do you do efficient array (de)referencing?

Expand Post »
I'm not going to go into much detail here; I've knocked up a lil example application to show where I'm having trouble; I'd like to know why $REF_DREF_A != $REF_DREF_B (and equally why there isn't a "hippo" qualifier to the "hello" in @DREF_B)...

But more importantly, can I easily make them the same, without wrapping "the array" in an object? I want to dereference the array (and still use it like an array), not clone it.

INPUT:
Perl Syntax (Toggle Plain Text)
  1. #!/usr/bin/perl
  2. my(@array) = ();
  3. push(@array,"hello");
  4. my($REF_A) = \@array;
  5. my($REF_B) = \@array;
  6. print "contents of source array:\n\n";
  7. print @array;
  8. print "\n\nreferences to the source array:\n\n";
  9. print "A: ".$REF_A." B: ".$REF_B;
  10. my(@DREF_A) = @$REF_A;
  11. my(@DREF_B) = @$REF_B;
  12. push(@DREF_A,"hippos");
  13. print "\n\ncontents of A dereferenced source array:\n\n";
  14. print @DREF_A;
  15. print "\n\ncontents of B dereferenced source array:\n\n";
  16. print @DREF_B;
  17. my($REF_DREF_A) = \@DREF_A;
  18. my($REF_DREF_B) = \@DREF_B;
  19. print "\n\nre-references to the source array:\n\n";
  20. print "A: ".$REF_DREF_A." B: ".$REF_DREF_B;
  21. print "\n\n";
OUTPUT:
Perl Syntax (Toggle Plain Text)
  1.  
  2. contents of source array:
  3. hello
  4. references to the source array:
  5. A: ARRAY(0x35fb0) B: ARRAY(0x35fb0)
  6. contents of A dereferenced source array:
  7. hellohippos
  8. contents of B dereferenced source array:
  9. hello
  10. re-references to the source array:
  11. A: ARRAY(0x1831e90) B: ARRAY(0x1831ec0)
  12. Press any key to continue . . .
Similar Threads
Moderator
Featured Poster
Reputation Points: 522
Solved Threads: 64
Veteran Poster
MattEvans is offline Offline
1,091 posts
since Jul 2006
Oct 8th, 2006
0

Re: How do you do efficient array (de)referencing?

you don't need to make a copy of the array referenced by a reference to use it. But you need to make a copy if you don't want the original variable the reference points to to be affected.

Quote ...
I'd like to know why $REF_DREF_A != $REF_DREF_B
because they are references to two different arrays:

my(@DREF_A) = @$REF_A;
my(@DREF_B) = @$REF_B;

my($REF_DREF_A) = \@DREF_A;
my($REF_DREF_B) = \@DREF_B;

@DREF_A and @DREF_B are two seperate variables even though they are two copies of the same data. So $REF_DREF_A and $REF_DREF_B are pointer to two seperate bits of data.
Reputation Points: 246
Solved Threads: 67
Practically a Posting Shark
KevinADC is offline Offline
898 posts
since Mar 2006
Oct 8th, 2006
0

Re: How do you do efficient array (de)referencing?

Hmm, I have ended up wrapping the array in an object for now.. My actual project is somewhat more advanced than that example; I need to be able to manipulate a number of arrays from many different "angles" without defining any kind of notification..

I can get READ access to the array without derefencing it, but write access (even by explicit index) doesn't seem to work for me without doing something like this:

my(@array) = ();
$self->{arrayref} = \@array;
 
then sometime later...
 
my($REF) = $self->{arrayref};
my(@array) = @{$REF};
push(@array,$data);
$self->{arrayref} = \@array;

That's pretty much what the object I'm using at the moment does at every access... Is this really the best way to go about it? Because it seems like there's an amount of uneccessary garbage being generated behind the scenes.
Moderator
Featured Poster
Reputation Points: 522
Solved Threads: 64
Veteran Poster
MattEvans is offline Offline
1,091 posts
since Jul 2006
Oct 8th, 2006
0

Re: How do you do efficient array (de)referencing?

I suppose, anything I do is going to have a similar overhead; it's always going to be neccessary to re-allocate sequential space to the array when the size changes..

I'm used to silence/seamlessness when using array references.

Maybe I'll use chained objects or psuedo-fixed-length arrays if it turns into a problem.. It's good to have an encapsulated array just-in-case
Moderator
Featured Poster
Reputation Points: 522
Solved Threads: 64
Veteran Poster
MattEvans is offline Offline
1,091 posts
since Jul 2006
Oct 9th, 2006
0

Re: How do you do efficient array (de)referencing?

you should be able to do something like this:


my $self = {};
my @array = qw(Mary had a little);
$self->{arrayref} = \@array;
push @{$self->{arrayref}},'lamb';#append new element  to array
print join(' ',@{$self->{arrayref}});
print "\n";
$self->{arrayref}->[0] = 'Joe';#change index 0 of array
print join(' ',@{$self->{arrayref}});
Reputation Points: 246
Solved Threads: 67
Practically a Posting Shark
KevinADC is offline Offline
898 posts
since Mar 2006
Oct 9th, 2006
0

Re: How do you do efficient array (de)referencing?

That's good; thanks for that, it works as I'd expect it to.

However, going back to my example...

If this:
Perl Syntax (Toggle Plain Text)
  1. my(@DREF_A) = @$REF_A;
  2. my(@DREF_B) = @$REF_B;
  3. push(@DREF_A,"hippos");

Is changed to this:
Perl Syntax (Toggle Plain Text)
  1. my(@DREF_A) = @$REF_A;
  2. push(@DREF_A,"hippos");
  3. my(@DREF_B) = @$REF_B;

Shouldn't that change the contents of @DREF_B? (The data should now be copied after the array is changed) It doesn't though, I've just checked it (same output as before).

Also, the @DREF_B output doesn't match the @DREF_A output even if both @DREF_A and @DREF_B are sourced from the same pointer, as in:

Perl Syntax (Toggle Plain Text)
  1. my(@DREF_A) = @$REF_A;
  2. push(@DREF_A,"hippos");
  3. my(@DREF_B) = @$REF_A;

Although it does work as per your example:
Perl Syntax (Toggle Plain Text)
  1. push(@$REF_A,"hippos");
  2. my(@DREF_A) = @$REF_A;
  3. my(@DREF_B) = @$REF_B;

Seems strange though! Shouldn't @$REF_A evaluate to the same thing whether its a subroutine parameter or a variable assignment?
Moderator
Featured Poster
Reputation Points: 522
Solved Threads: 64
Veteran Poster
MattEvans is offline Offline
1,091 posts
since Jul 2006
Oct 9th, 2006
1

Re: How do you do efficient array (de)referencing?

Click to Expand / Collapse  Quote originally posted by MattEvans ...
That's good; thanks for that, it works as I'd expect it to.

However, going back to my example...

If this:
Perl Syntax (Toggle Plain Text)
  1. my(@DREF_A) = @$REF_A;
  2. my(@DREF_B) = @$REF_B;
  3. push(@DREF_A,"hippos");

Is changed to this:
Perl Syntax (Toggle Plain Text)
  1. my(@DREF_A) = @$REF_A;
  2. push(@DREF_A,"hippos");
  3. my(@DREF_B) = @$REF_B;

Shouldn't that change the contents of @DREF_B? (The data should now be copied after the array is changed) It doesn't though, I've just checked it (same output as before)

No. @DREF_A and @DREF_B are copies of whatever reference you dereferenced at that point. They are entirely seperate from the original data at that point.

Also, the @DREF_B output doesn't match the @DREF_A output even if both @DREF_A and @DREF_B are sourced from the same pointer, as in:

Perl Syntax (Toggle Plain Text)
  1. my(@DREF_A) = @$REF_A;
  2. push(@DREF_A,"hippos");
  3. my(@DREF_B) = @$REF_A;

Same reason. @DREF_A has no connection to $REF_A anymore. @DREF_B will have the value of $REF_A. You did not make any changes to $REF_A, you made a copy of it and changed the value of the copy (@DREF_A)'

Although it does work as per your example:
Perl Syntax (Toggle Plain Text)
  1. push(@$REF_A,"hippos");
  2. my(@DREF_A) = @$REF_A;
  3. my(@DREF_B) = @$REF_B;

Seems strange though! Shouldn't @$REF_A evaluate to the same thing whether its a subroutine parameter or a variable assignment?

In the above you changed the value of the original data that $REF_A points to. Then you make two new copies which will both have the same value because $REF_A and $REF_B are pointers to the same data.
Reputation Points: 246
Solved Threads: 67
Practically a Posting Shark
KevinADC is offline Offline
898 posts
since Mar 2006

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Perl Forum Timeline: Execute Unix commands from Perl script
Next Thread in Perl Forum Timeline: Rather strange problem copying, need assistance.





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC