Start with an array my @arr = (1,2,3); Get a reference to it my $ref = \@arr; my $ref1 = \@arr; Note that ref and ref1 point to the same array, they are the same memory location: print $ref." and ".$ref1; Access elements: print $arr[1]; print $ref->[1];
Or start with a (array) reference my $ref = [1,2,3]; "Dereference" it: my @arr = @{$ref}; print $arr[1];
An array can hold scalars as well as references to other arrays or any other data structure or object. So in my @arr = (1,2,3, [7,8,9]); print $arr[1]; print $arr[3]->[1]; , the $arr[3] is a reference and its elements must be accessed using '->[]' as opposed to '[]'. Note that "->" can be used to access the internals (i.e. inside the memory space where the reference points to) of other types of references, e.g. the value from a hashref given the key or execute a subroutine inside an object. A "proper" 2D array, the way you want it, is just a 1D array whose 2 elements are references to other arrays: my @arr = ([1,2,3],[4,5,6]);
And multi-dimensional arrays need not be rectangular or homogeneous as this shows: my @arr = (1,2,3, [7,8,9], File::Find::Node->new("/home/bliako") );
If you have a C background these things are common and inbred. But if you don't, then you may wonder why things are not as simple as: @arr = ( (1,2,3), (4,5,6) ); This in actuality concatenates the two sub-arrays into a 1D array (as I understand it). I guess it would be too much dumping down for Perl to allow you to specify a 2D array this way and allow you (let alone "lead you") to abstract completely the hardware underneath and forget that RAM is 1D.
This is also useful in order to demonstrate the above point: $ref = [1,2,3]; @arr = ($ref, $ref); $arr[0]->[1] = 66; print $ref->[1]; print $arr[1]->[1]; $ref->[1] = 33; print $arr[0]->[1];
Or this: $ref = [1,2,3]; @arr = ($ref); $ref = [4,5,6]; push @arr, $ref; print $arr->[0]->[1]; print $arr->[1]->[1];
References are memory addresses pointing to the real data structure or object. They are useful in that you can pass them around to subroutines without risking making copies to the whole data structure (re: https://www.effectiveperlprogramming.com/2010/05/use-scalar-references-to-pass-large-data-without-copying). Most importantly, you can have the subroutine modifying items inside the data structure. That's why I learned to love them. Strange love indeed! A program can be written without using a @arr = (...); at all, but only $ref = [...];
Edit: "memory addresses pointing to the real data structure" maybe I should rephrase this to "they are the starting address of the memory where the real data structure resides". Also fixed ref1 and ref2.
bw, bliako
In reply to Re: Multi-Dimensional Arrays and Array References
by bliako
in thread Multi-Dimensional Arrays and Array References
by Leudwinus
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |