in reply to Trying to learn about References

As you say, one good reason for references is to build complex data structures. Another is to pass arrays and hashes into and out of subroutines. And, of course, all of Perl's OO capability is based on references.

Many people find perlref to be a bit dry on first reading. That's why Dominus wrote perlreftut. You might find that makes a bit more sense to you.

--
<http://www.dave.org.uk>

"The first rule of Perl club is you do not talk about Perl club."
-- Chip Salzenberg

Replies are listed 'Best First'.
Re: Re: Trying to learn about References
by dru145 (Friar) on Jan 04, 2002 at 20:39 UTC
    Thanks for the suggestion Dave. I actually went through my perl library and found a very good explanation on refernces in Elements of Programming Perl and it started sinking in.

    Dru
    Another satisfied monk.
Re: Re: Trying to learn about References
by vladb (Vicar) on Jan 05, 2002 at 03:23 UTC
    Another good use for references is to avoid making 'copies' of data that is being passed to a sub in the arguments list (you simply pass addresses to given variables so that you may use those addresses -- references -- inside the sub to access original variable values). Passing references to original variables may also prove useful when you see a need in modifying the original variable inside a subroutine.
    Here's a pretty basic exaple:
    sub by_val { my ($foo) = @_; print "Foo = $foo\n"; $foo = 10; # only 'foo' belonging to this sub is modifi +ed } sub by_ref { my ($foo_ref) = @_; print "Foo = $$foo_ref\n"; # pring value in 'bar' $$foo_ref = 10; # will modify 'bar' } my $bar = 5; by_val($bar); print "bar = $bar\n"; by_ref(\$bar); # $bar may no be modified inside the sub. print "bar = $bar\n";

    I'm also a fan of using references when passing large chunks of text (string variables) around to be used in various subroutines. This again boils down to not having to copy contents of a variable.

    "There is no system but GNU, and Linux is one of its kernels." -- Confession of Faith
      A lot of what you said isn't correct. For example, you said:
      I'm also a fan of using references when passing large chunks of text (string variables) around to be used in various subroutines. This again boils down to not having to copy contents of a variable.
      This is erroneous, because when you pass a string to a subroutine, Perl does not copy the contents of the variable. And you made the same mistake when you named one of your example subroutines by_val. Perl does not pass scalar data by value. Scalar data is always passed by reference, whether you use an explicit reference or not.

      Consider:

      sub trim { $_[0] =~ s/^\s+//; $_[0] =~ s/\s+$//; $_[0]; } my $var = " I like pie. "; trim($var); print $var;
      The call to the trim function actually modifies $var, because scalar data is passed by reference, not by value. The value of $var is not copied.

      The technique you suggest is more useful for arrays and hashes. foo(@array) passes a (possibly long) list of scalars to foo(), but foo(\@array) passes only a single reference.

      --
      Mark Dominus
      Perl Paraphernalia

        Certainly I agree with what you said. Thanks for your comments ;-). Probably, what I _really_ meant is doing something like
        my ($in) = @_;
        will initialize a new variable $in with the contents of the first argument.. and if it's other than a reference the cost of doing so may be high if the data to be thus 'copied' is substantial.

        I've done a bit more playing with Devel::Peek module which allows one to look inside the Perl variables (look up their guts sort of ;-):
        #!/usr/local/bin/perl use Devel::Peek 'Dump'; sub foo { # this will create a new variable $s and copy first argument's con +tents right? my ($s) = @_; print "Dump inside trim():\n"; print "\$_[0] (this one is infact a 'synonym' to the actual variab +le; not it's copy :-) :\n"; Dump($_[0]);print"\n"; print "\$s (this is a copy of the 1-st argument:\n"; Dump($s);print"\n"; } sub bar(\$) { # this will create a new variable $s and copy first argument's con +tents as well, # however, it's much faster here compred to foo() since in this ca +se only # a reference to the actual variable is copied, not the actual var +iable's # contents. my ($s) = @_; print "Dump inside bar(\\\$):\n"; print "\$_[0]:\n"; Dump($_[0]);print"\n"; print "\$s (this is a copy of the 1-st argument, which is nothing +more but a reference..):\n"; Dump($s);print"\n"; } $s = "some text here "; print "Dump before:\n"; Dump($s);print"\n"; foo($s); bar($s); print "Dump after:\n"; Dump($s);print"\n";
        And here's the output produced by this script:
        Dump before: SV = PV(0xf0c44) at 0xfe99c REFCNT = 1 FLAGS = (POK,pPOK) PV = 0xf7560 "some text here "\0 CUR = 15 LEN = 16 Dump inside trim(): $_[0] (this one is infact a 'synonym' to the actual variable; not it's + copy :-) : SV = PV(0xf0c44) at 0xfe99c REFCNT = 1 FLAGS = (POK,pPOK) PV = 0xf7560 "some text here "\0 CUR = 15 LEN = 16 $s (this is a copy of the 1-st argument: SV = PV(0xf0c98) at 0xfe9c0 REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK) PV = 0xf7540 "some text here "\0 CUR = 15 LEN = 16 Dump inside bar(\$): $_[0]: SV = RV(0x11581c) at 0xf096c REFCNT = 1 FLAGS = (ROK) RV = 0xfe99c SV = PV(0xf0c44) at 0xfe99c REFCNT = 3 FLAGS = (POK,pPOK) PV = 0xf7560 "some text here "\0 CUR = 15 LEN = 16 $s (this is a copy of the 1-st argument, which is nothing more but a r +eference..): SV = RV(0x115828) at 0x1164b0 REFCNT = 1 FLAGS = (PADBUSY,PADMY,ROK) RV = 0xfe99c SV = PV(0xf0c44) at 0xfe99c REFCNT = 3 FLAGS = (POK,pPOK) PV = 0xf7560 "some text here "\0 CUR = 15 LEN = 16 Dump after: SV = PV(0xf0c44) at 0xfe99c REFCNT = 1 FLAGS = (POK,pPOK) PV = 0xf7560 "some text here "\0 CUR = 15 LEN = 16
        Certainly, the difference is subtle. And, also, '$_[0]' itself is not a copy of the source variable, but rather it's 'synonym' or reference (c-like). However, most of the time it's much easier to simply pass around references just in case, at least that's how me thinks ;-)...

        "There is no system but GNU, and Linux is one of its kernels." -- Confession of Faith