Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

pass by reference

by bivouac (Beadle)
on Nov 07, 2003 at 18:18 UTC ( [id://305388]=perlquestion: print w/replies, xml ) Need Help??

bivouac has asked for the wisdom of the Perl Monks concerning the following question:

I think the next world for me to conquer in Perl is references; I really seem to struggle with the concept and the use.

I've been reading the perldoc reftut and the concept still escapes me.

What I am understanding is that when you pass a reference to a function, you're not passing a copy of the referant but the referant itself (I think, like I said I don't get references too well). With the code I'm enclosing below, how could I play around with the concept of changing something via the use of a reference and a function and then see the results of the change in the main block of data.

#!/usr/bin/perl -w use strict; my %horoscopes = ( 'homer' => 'pisces', 'marge' => 'sagitarius', 'bart' => 'cancer', 'libra' => 'libra', ); my $reference = \%horoscopes; capitalize($reference); sub capitalize { foreach (keys(%{$reference})) { tr/[a-z]/[A-Z]/; } }

Replies are listed 'Best First'.
Re: pass by reference
by Zaxo (Archbishop) on Nov 07, 2003 at 18:36 UTC

    Your treatment of references here is completely correct. The problem with the code is that sub capitalize does not actually change anything in the hash passed to it, as well as having argument passing problems. If you want to change the keys of the hash, try this,

    sub capitalize { my $hashref = shift; foreach ( keys %$hashref ) { $hashref->{ uc($_) } = delete $hashref->{$_}; } 1; }
    delete returns the value of the deleted item. That idiom is the way to rekey a hash.

    After Compline,
    Zaxo

Re: pass by reference
by Limbic~Region (Chancellor) on Nov 07, 2003 at 18:31 UTC
    bivouac,
    Your problem isn't with the concept of references, it is with the hash itself. Have you tried running the code without the sub? It will not change the case of the keys.
    #!/usr/bin/perl -w use strict; my %horoscopes = ( 'homer' => 'pisces', 'marge' => 'sagitarius', 'bart' => 'cancer', 'libra' => 'libra' ); capitalize(\%horoscopes); sub capitalize { my $hash = shift; for my $key (keys %{$hash}) { $hash->{uc $key} = $hash->{$key}; delete $hash->{$key}; } }
    The problem is you haven't defined what you want to happen if an uppercase key by the same name already exists.

    Cheers - L~R

Re: pass by reference
by Zed_Lopez (Chaplain) on Nov 07, 2003 at 20:08 UTC

    Perl subroutines are always call-by-reference.

    my $a = 10; print "$a "; change($a); print "$a"; sub change { $_[0]++; }
    produces 10 11.

    The standard practice of making copies of the subroutine parameters functionally turns this into call-by-value.

    my $a = 10; print "$a "; change($a); print "$a"; sub change { my $param = shift; $param++; }
    produces 10 10.

    But if you're passing an explicit reference, then a copy of the reference still refers to the original referent.

    # contrived example: there usually isn't a good reason # to have references to scalars. my $a = 10; my $b = \$a; print "$$b "; change($b); print "$$b"; sub change { my $param = shift; ${$param}++; }
    produces 10 11.

    ...but the subroutine parameter was still an alias of the original reference, and so its value (not just the referent's value) can be changed, just as in the first example.

    my $a = 10; my $b = \$a; my $c = 4; print "$$b "; change($b); print "$$b"; sub change { $_[0] = \$c; }
    produces 10 4.

    You usually won't write code like the first or last examples -- but it's good to understand all this.

Re: pass by reference
by shockme (Chaplain) on Nov 07, 2003 at 18:26 UTC
    Here's a couple of items to help you along your way:

    References by busunsl
    References quick reference by tye

    These are both very good tutorials, and you probably find most (if not all) of your questions answered there.

    If things get any worse, I'll have to ask you to stop helping me.

Re: pass by reference
by Taulmarill (Deacon) on Nov 07, 2003 at 18:32 UTC
    hm, i would suggest to do something like
    &capitalise( \%horoscopes ); sub capitalise { my $values = shift; foreach ( keys ( %{$values} ) ) { .... ...this is not tested...
    because i think you want to give your sub a reference on the hash %horoscopes. but what you actualy did is to store a reference in $reference and give it to the sub but you used the scalar reference from the main program.
    you should not only read the reftut again but read perlsub too.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://305388]
Approved by valdez
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (2)
As of 2024-04-25 23:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found