FAQ
Hi,

I came across this problem and thought I'd run it by the list so that perhaps someone can explain to me what is going on

Given a script with the following hash definition

#!/usr/bin/perl

use warnings;
use strict;

my %sib_master_hoa = (
XXXX => [ 'XXXX <type>' ] ,
XXXX_ERSALL => [ 'XXXX <type>', 'ERS CRCODOSS <type>', 'ERS ENVDOSS <type>', 'ERS ENVVAL <type>' ],
XXXX_ERSOTHERS => [ 'XXXX <type>', 'ERS CRCODOSS <type>', 'ERS ENVVAL <type>' ],
);

sub AddGroup {
my ($sib_user, $sib_profile, $sib_sibprofx) = @_;
#
for my $profile ( @{ $sib_master_hoa{$sib_profile} } ) {
$profile =~ s/<type>/$sib_sibprofx/g;
print "-A $sib_user -g $profile\n";
}

} #
# Main MAIN #

AddGroup("jerry","XXXX","ONE");
AddGroup("laurence","XXXX","TWO");
AddGroup("ralf","XXXX_ERSALL","ONE");
AddGroup("randal","XXXX_ERSALL","TWO")
#EOF

The output I get is:

-A jerry -g XXXX ONE
-A laurence -g XXXX ONE
-A ralf -g XXXX ONE
-A ralf -g ERS CRCODOSS ONE
-A ralf -g ERS ENVDOSS ONE
-A ralf -g ERS ENVVAL ONE
-A randal -g XXXX ONE
-A randal -g ERS CRCODOSS ONE
-A randal -g ERS ENVDOSS ONE
-A randal -g ERS ENVVAL ONE

The values in the array in the hash are being changed but not by me ?

I've run this on perl, v5.8.0 built for PA-RISC1.1-thread-multi and perl, v5.6.1 built for x86_64-linux with the
same result.

If I define the hash inside the function I don't get the problem but I'm still confused about what is going on. I've
never seen anywhere yet that I can't define this kind of hash globally. This of course does not mean no one has said
it.

Thanks in advance for any ideas.


Jerry

Search Discussions

  • Shawn H Corey at Sep 17, 2009 at 12:43 pm

    Jerry Rocteur wrote:
    Hi,

    I came across this problem and thought I'd run it by the list so that perhaps someone can explain to me what is going on

    Given a script with the following hash definition

    #!/usr/bin/perl

    use warnings;
    use strict;

    my %sib_master_hoa = (
    XXXX => [ 'XXXX <type>' ] ,
    XXXX_ERSALL => [ 'XXXX <type>', 'ERS CRCODOSS <type>', 'ERS ENVDOSS <type>', 'ERS ENVVAL <type>' ],
    XXXX_ERSOTHERS => [ 'XXXX <type>', 'ERS CRCODOSS <type>', 'ERS ENVVAL <type>' ],
    );

    sub AddGroup {
    my ($sib_user, $sib_profile, $sib_sibprofx) = @_;
    #
    for my $profile ( @{ $sib_master_hoa{$sib_profile} } ) {
    for my key ( @{ $sib_master_hoa{$sib_profile} } ) {
    my $profile = $key;

    # See `perldoc perlsyn` and search for /Foreach Loops/;
    $profile =~ s/<type>/$sib_sibprofx/g;
    print "-A $sib_user -g $profile\n";
    }

    } #
    # Main MAIN #

    AddGroup("jerry","XXXX","ONE");
    AddGroup("laurence","XXXX","TWO");
    AddGroup("ralf","XXXX_ERSALL","ONE");
    AddGroup("randal","XXXX_ERSALL","TWO")
    #EOF __END__
    The output I get is:

    -A jerry -g XXXX ONE
    -A laurence -g XXXX ONE
    -A ralf -g XXXX ONE
    -A ralf -g ERS CRCODOSS ONE
    -A ralf -g ERS ENVDOSS ONE
    -A ralf -g ERS ENVVAL ONE
    -A randal -g XXXX ONE
    -A randal -g ERS CRCODOSS ONE
    -A randal -g ERS ENVDOSS ONE
    -A randal -g ERS ENVVAL ONE

    The values in the array in the hash are being changed but not by me ?

    I've run this on perl, v5.8.0 built for PA-RISC1.1-thread-multi and perl, v5.6.1 built for x86_64-linux with the
    same result.

    If I define the hash inside the function I don't get the problem but I'm still confused about what is going on. I've
    never seen anywhere yet that I can't define this kind of hash globally. This of course does not mean no one has said
    it.

    Thanks in advance for any ideas.
    You're welcome :)


    --
    Just my 0.00000002 million dollars worth,
    Shawn

    Programming is as much about organization and communication
    as it is about coding.

    I like Perl; it's the only language where you can bless your
    thingy.
  • Uri Guttman at Sep 17, 2009 at 4:28 pm
    "JR" == Jerry Rocteur writes:
    JR> my %sib_master_hoa = (
    JR> XXXX => [ 'XXXX <type>' ] ,
    JR> XXXX_ERSALL => [ 'XXXX <type>', 'ERS CRCODOSS <type>', 'ERS ENVDOSS <type>', 'ERS ENVVAL <type>' ],
    JR> XXXX_ERSOTHERS => [ 'XXXX <type>', 'ERS CRCODOSS <type>', 'ERS ENVVAL <type>' ],
    JR> );

    this is a good place to show how to better format nested structures like
    that. EVERYONE here should note this: :)

    my %sib_master_hoa = (
    XXXX => [
    'XXXX <type>'
    ],
    XXXX_ERSALL => [
    'XXXX <type>',
    'ERS CRCODOSS <type>',
    'ERS ENVDOSS <type>',
    'ERS ENVVAL <type>',
    ],
    XXXX_ERSOTHERS => [
    'XXXX <type>',
    'ERS CRCODOSS <type>',
    'ERS ENVVAL <type>',
    ],
    );

    nested data should be indented and arrays listed in columns (unless they
    are very short). note that each element ends in a comma as perl allows
    it. it makes for easier cut/pasting of data lines so you don't have to
    worry about which data ends in commas or not.


    JR> sub AddGroup {
    JR> my ($sib_user, $sib_profile, $sib_sibprofx) = @_;
    JR> #
    JR> for my $profile ( @{ $sib_master_hoa{$sib_profile} } ) {

    $profile is aliased to each element of the list, not a copy.
    JR> $profile =~ s/<type>/$sib_sibprofx/g;

    so that line modifies the elements of the list in the original hash.

    JR> print "-A $sib_user -g $profile\n";
    JR> }

    the solution is to either copy the list or the element.

    my @profiles = @{ $sib_master_hoa{$sib_profile} } ;
    for my $profile ( @profiles ) {

    or

    (my $new_prof = $profile ) =~ s/<type>/$sib_sibprofx/g;

    and print $new_prof.

    uri

    --
    Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedSep 17, '09 at 12:16p
activeSep 17, '09 at 4:28p
posts3
users3
websiteperl.org

People

Translate

site design / logo © 2021 Grokbase