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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.