Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re: Pointers and References

by kcott (Bishop)
on Nov 23, 2020 at 04:40 UTC ( #11124049=note: print w/replies, xml ) Need Help??


in reply to Pointers and References

G'day Leudwinus,

"I am still trying to wrap my head around ..."

You're using terms — pointer, address, memory location — which I suspect you've picked up from one or more other languages. You are then attempting to apply those terms to Perl, assuming they have the same meaning. I think this may be the source of your problems.

I'd suggest the first thing to do would be to look at perlintro; in particular, the "Perl variable types" section. At the end of that section you'll find the gentlest of introductions to references with a list of other links to more information; I'd suggest checking out perlreftut first.

Consider the following:

$ perl -E ' my $x = 5; say $x; my $y = \$x; say $y; say $$y; $$y += 3; say $x; ' 5 SCALAR(0x60008a1c8) 5 8
  • $x has the value 5.
  • $y is assigned a reference to $x.
  • $y has the value SCALAR(0x60008a1c8).
  • Dereferencing $y (with $$y) gives you back $x.
  • Incrementing $$y by 3 is the same as incrementing $x by 3.
  • $x now has the value 8.

You can reference and dereference to great depths if you want; as in this exaggerated example:

$ perl -E 'my $x = 5; say $x; my $y = \\\\$x; $$$$$y += 3; say $x' 5 8

The construct \(...), where ... is some list, evaluates to a list of references to each element of the list:

$ perl -E 'say for \(qw{1 2 3})' SCALAR(0x60008a730) SCALAR(0x60008a7d8) SCALAR(0x60008a748)

You can take references to other data types:

$ perl -E 'my @x = qw{1 2 3}; say for @x; my $y = \@x; say $y' 1 2 3 ARRAY(0x60008a8e8)

and dereference them:

$ perl -E 'my @x = qw{1 2 3}; say for @x; my $y = \@x; say $y; say for + @$y' 1 2 3 ARRAY(0x60008a828) 1 2 3

You can take references to references:

$ perl -E 'my @x = qw{1 2 3}; say for @x; my $y = \\@x; say $y' 1 2 3 REF(0x600003e80)

and dereference them one level at a time:

$ perl -E 'my @x = qw{1 2 3}; say for @x; my $y = \\@x; say $y; say $$ +y; say for @$$y' 1 2 3 REF(0x600003e80) ARRAY(0x60008a868) 1 2 3

I suggest you play around with examples like these to get a better understanding of how all of this works.

Also note that I didn't use, or indeed need, terms such as pointer, address or memory location.

You used strict and warnings in your OP which is very good. I suggest you do the same with oneliners. Here's a common alias I use; you might want to set up something similar for yourself (although, perhaps, one a little less involved).

$ alias perle alias perle='perl -Mstrict -Mwarnings -Mautodie=:all -MCarp::Always -E +'

That will pick up things like this:

$ perl -E '$x =5' $ perle '$x =5' Global symbol "$x" requires explicit package name (did you forget to d +eclare "my $x"?) ... $ perl -E 'my $x = 5; say @$x' $ perle 'my $x = 5; say @$x' Can't use string ("5") as an ARRAY ref while "strict refs" in use ...

— Ken

Replies are listed 'Best First'.
Re^2: Pointers and References
by Leudwinus (Beadle) on Nov 25, 2020 at 17:36 UTC

    Hi Ken,

    You're using terms pointer, address, memory location which I suspect you've picked up from one or more other languages. You are then attempting to apply those terms to Perl, assuming they have the same meaning. I think this may be the source of your problems.

    Guilty as charged! I was trying to replicate in Perl the following program from a C tutorial on functions and pointers:

    #include <stdio.h> int sum_and_diff (int a, int b, int *res) { int sum; sum = a + b; *res = a b; return sum; } void main (void) { int b = 2; int diff; printf ("The sum of 5 and %d is %d\n", b, sum_and_diff (5, b, &diff)); printf ("The difference of 5 and %d is %d\n", b, diff); }

    Perhaps I just need to focus on one language at a time! And thank you for the detailed example and explanation!

    You can reference and dereference to great depths if you want; as in this exaggerated example

    I'm just reading this now but came to the same conclusion earlier today when I was reading some of the other responses to this thread.

    I suggest you play around with examples like these to get a better understanding of how all of this works.

    Agreed. What I take away from your examples is that when I try to print or output a variable that contains a reference, I can clearly see what that is in reference to. For example:

    SCALAR(0x60008a730) --> reference to a scalar ARRAY(0x60008a828) --> reference to an array REF(0x600003e80) --> reference to a reference

    This helps you understand how to dereference it:

    $$x # dereference reference to scalar (if $x is a scalar) @$x # dereference reference to array (if $x is reference to an array) @$$x # dereference reference to reference of an array

    I hope I got that last bit right!

    Also note that I didn't use, or indeed need, terms such as pointer, address or memory location.

    Duly noted! And thanks for the alias tip. I will have to park that one away for the time being because as useful as Perl one-liners are, I don't think I'm quite ready to use them that frequently.

    Gratias tibi ago
    Leudwinus

      "And thanks for the alias tip. I will have to park that one away for the time being because as useful as Perl one-liners are, I don't think I'm quite ready to use them that frequently."

      I have aliases set up such that they're always available, regardless of frequency of usage. In ~/.bashrc, I have:

      ... if [ -f "${HOME}/.bash_aliases" ]; then . "${HOME}/.bash_aliases" fi ...

      And ~/.bash_aliases has lines like this:

      ... alias vi='vim' alias view='vim -R' ... alias perle='perl -Mstrict -Mwarnings -Mautodie=:all -MCarp::Always -E +' alias perlb='perl -MO=Deparse,-p -e' ... alias apache_up='/usr/sbin/apachectl start' alias apache_down='/usr/sbin/apachectl stop' ...

      You may need to adjust to suit whatever shell you're using; however, the basic principle should be applicable to any UNIX-like system. I use this with Linux for $work; with Cygwin for personal, home use; and, up until a year or so ago, with macOS (formerly Mac OS X).

      — Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11124049]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (8)
As of 2021-01-19 16:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?