Home of the Squeezebox™ & Transporter® network music players.
Results 1 to 5 of 5
  1. #1
    Senior Member
    Join Date
    Apr 2005
    Location
    UK/London
    Posts
    4,771

    Perl - pass by reference v pass by value

    In the old days when I was a programmer in a long forgotten language (Coral-66) it was really clear if you were using a value or a reference/location when working with stuff.

    I have just been caught out with this in Perl and would like to know the correct way to make the setting of variable $newvalue below to be a value and not a reference.

    Here is example code:
    Code:
    use Data::Dumper;
    my $dumped;
    
    my $variable1 = {
        subarray => ['abc1', 'abc2']
    };
    
    
    $dumped = Dumper $variable1;
    print "Original: $dumped\n";
    
    foreach my $newvalue ( @{$variable1->{subarray}} ){
        print "subarray value: $newvalue\n";
        $newvalue = 'a new string';
    }
    
    $dumped = Dumper $variable1;
    print "Original has been changed: $dumped\n";
    and here is the output
    Code:
    Original: $VAR1 = {
              'subarray' => [
                              'abc1',
                              'abc2'
                            ]
            };
    
    subarray value: abc1
    subarray value: abc2
    Original has been changed: $VAR1 = {
              'subarray' => [
                              'a new string',
                              'a new string'
                            ]
            };
    I did not expect that the values in $variable1 to change through me changing a new local variable $newvalue.
    Paul Webster
    http://dabdig.blogspot.com
    Author of "Now Playing" plugins covering Radio France (FIP etc), PlanetRadio (Bauer - Kiss, Absolute, Scala, JazzFM etc), KCRW, ABC Australia, CBC/Radio-Canada and RTE Ireland
    and, via the extra "Radio Now Playing" plugin, AllZIC Radio, Caroline Flashback, Cesky rozhlas, Frequence3, JukeRadio, KlassikRadio.de, Linn Radio, Mother Earth, Naim Radio, Nova.fr, RadioBlues Flac, Radio Espace, Somehow Jazz, Supla Finland

  2. #2
    Senior Member
    Join Date
    Apr 2005
    Location
    UK/London
    Posts
    4,771
    One quick hack until someone suggests the right way to do it is simply to add a new variable can copy to it then work with that ...

    Code:
    my $anothervalue = $newvalue;
        
    $anothervalue = 'another value';
    Paul Webster
    http://dabdig.blogspot.com
    Author of "Now Playing" plugins covering Radio France (FIP etc), PlanetRadio (Bauer - Kiss, Absolute, Scala, JazzFM etc), KCRW, ABC Australia, CBC/Radio-Canada and RTE Ireland
    and, via the extra "Radio Now Playing" plugin, AllZIC Radio, Caroline Flashback, Cesky rozhlas, Frequence3, JukeRadio, KlassikRadio.de, Linn Radio, Mother Earth, Naim Radio, Nova.fr, RadioBlues Flac, Radio Espace, Somehow Jazz, Supla Finland

  3. #3
    Senior Member philchillbill's Avatar
    Join Date
    Jan 2019
    Location
    The Netherlands
    Posts
    822
    In Perl, foreach operates on the original array. If you modify the loop variable then that modification is reflected in the original array.

  4. #4
    Senior Member
    Join Date
    Apr 2005
    Location
    UK/London
    Posts
    4,771
    Yep - I’ve worked that out and have been through all of my foreach… @ to check and correct (in the very small number of places that I had modified the value).
    Tricky one to spot but I noticed from some other code of mine that I must have realised this before because I had a similar solution in one other place.
    Ah well … we live and learn … and forget.
    Paul Webster
    http://dabdig.blogspot.com
    Author of "Now Playing" plugins covering Radio France (FIP etc), PlanetRadio (Bauer - Kiss, Absolute, Scala, JazzFM etc), KCRW, ABC Australia, CBC/Radio-Canada and RTE Ireland
    and, via the extra "Radio Now Playing" plugin, AllZIC Radio, Caroline Flashback, Cesky rozhlas, Frequence3, JukeRadio, KlassikRadio.de, Linn Radio, Mother Earth, Naim Radio, Nova.fr, RadioBlues Flac, Radio Espace, Somehow Jazz, Supla Finland

  5. #5
    jvromans@squirrel.nl
    Guest

    Perl - pass by reference v pass by value

    On Tue, 21 Sep 2021 09:09:46 +0000, Paul Webster
    <Paul.Webster.a8bjuo (AT) no-mx (DOT) forums.slimdevices.com> wrote:

    > I did not expect that the values in $variable1 to change through me
    > changing a new local variable $newvalue.


    That is because my is not necessarily introducing a local variable. When
    used in an iteration

    foreach my $var ( $x ) {
    # $var is an alias to $x

    $var becomes an _alias_ to the value referenced. If you modify it, you
    modify the original.

    If you don't want that, the correct syntax is

    foreach ( ... ) {
    my $var = $_; # now the value is copied

    HTH,
    Johan

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •