| | |
How do you do efficient array (de)referencing?
![]() |
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:
OUTPUT:
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)
#!/usr/bin/perl my(@array) = (); push(@array,"hello"); my($REF_A) = \@array; my($REF_B) = \@array; print "contents of source array:\n\n"; print @array; print "\n\nreferences to the source array:\n\n"; print "A: ".$REF_A." B: ".$REF_B; my(@DREF_A) = @$REF_A; my(@DREF_B) = @$REF_B; push(@DREF_A,"hippos"); print "\n\ncontents of A dereferenced source array:\n\n"; print @DREF_A; print "\n\ncontents of B dereferenced source array:\n\n"; print @DREF_B; my($REF_DREF_A) = \@DREF_A; my($REF_DREF_B) = \@DREF_B; print "\n\nre-references to the source array:\n\n"; print "A: ".$REF_DREF_A." B: ".$REF_DREF_B; print "\n\n";
Perl Syntax (Toggle Plain Text)
contents of source array: hello references to the source array: A: ARRAY(0x35fb0) B: ARRAY(0x35fb0) contents of A dereferenced source array: hellohippos contents of B dereferenced source array: hello re-references to the source array: A: ARRAY(0x1831e90) B: ARRAY(0x1831ec0) Press any key to continue . . .
Plato forgot the nullahedron..
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.
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.
•
•
•
•
I'd like to know why $REF_DREF_A != $REF_DREF_B
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.
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:
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.
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.
Plato forgot the nullahedron..
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
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
Plato forgot the nullahedron..
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}});
That's good; thanks for that, it works as I'd expect it to.
However, going back to my example...
If this:
Is changed to this:
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:
Although it does work as per your example:
Seems strange though! Shouldn't @$REF_A evaluate to the same thing whether its a subroutine parameter or a variable assignment?
However, going back to my example...
If this:
Perl Syntax (Toggle Plain Text)
my(@DREF_A) = @$REF_A; my(@DREF_B) = @$REF_B; push(@DREF_A,"hippos");
Is changed to this:
Perl Syntax (Toggle Plain Text)
my(@DREF_A) = @$REF_A; push(@DREF_A,"hippos"); 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)
my(@DREF_A) = @$REF_A; push(@DREF_A,"hippos"); my(@DREF_B) = @$REF_A;
Although it does work as per your example:
Perl Syntax (Toggle Plain Text)
push(@$REF_A,"hippos"); my(@DREF_A) = @$REF_A; 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?
Plato forgot the nullahedron..
•
•
•
•
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)
my(@DREF_A) = @$REF_A; my(@DREF_B) = @$REF_B; push(@DREF_A,"hippos");
Is changed to this:
Perl Syntax (Toggle Plain Text)
my(@DREF_A) = @$REF_A; push(@DREF_A,"hippos"); 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)
my(@DREF_A) = @$REF_A; push(@DREF_A,"hippos"); 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)
push(@$REF_A,"hippos"); my(@DREF_A) = @$REF_A; 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.
![]() |
Similar Threads
Other Threads in the Perl Forum
- Previous Thread: Execute Unix commands from Perl script
- Next Thread: Rather strange problem copying, need assistance.
| Thread Tools | Search this Thread |






