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

Hello respected Monks, Here is my question I have a line of code like so: "$dub_key => $dub_values\n"; that prints dubhpr28.hpux => ARRAY(0x4002e1bc) but I want to have printed out the values contained in the $dub_values arrayref instead of its address. What do I have to change to achieve this? My Goal is below key=>dubhpr01.hpux values=>name,uid,gid,comments. dublin_aref = \@dublin_array. @dublin_arry contains a glob like so: glob("/home/user/passwd.*) dub_values are the values within the hash %dublin_hosts while dub_key is the regexp from the filenames that is the key within the hash %dublin_hosts. As an example, each key is the regexp of each file name from the array reference: passwd.dubhpr01.hpux after being parsed by my regexp I get dubhpr01.hpux Each values are the various fields in the passwd files. Here is the snippet of code I am working on now:
1 use strict; 2 use warning; 3 use diagnostics; 4 5 my @dublinaray = glob("/home/user/passwd.*"); 6 my $dublin_aref = \@dublinaray; 7 my (%dublin_hosts) = (); 8 my ($dub_key,$dub_values,); 9 10 parse_file(); 11 12 13 sub parse_file { 14 foreach my $element ( @{$dublin_aref} ) { 15 { local *FILE; 16 open (FILE, "+<$element") or die "dublin reference did not open: $!"; 17 local $/ = undef; 18 ($dub_key) = $element =~ m|\.(\w+\.\w+)\z|i; 19 ($dub_values) = split /:/, <FILE>; 20 push ( @{$dublin_hosts{$dub_key}}, $dub_values ); 21 print Dumper("KEY\t",$dub_key,"\n\n"); 22 print Dumper("ELEMENTS\t",$element,"\n\n"); 23 print Dumper("DUB VALUES\t",$dub_values,"\n\n"); 24 } 25 } 26 while ( ($dub_key,$dub_values) = each %dublin_hosts ) { 27 print Dumper("$dub_key => $dub_values\n"); 28 } 29 30 } ##-- END SUB --## ## thank you!

Replies are listed 'Best First'.
Re: printing array reference and storing this data in a hash.
by ferreira (Chaplain) on Dec 19, 2006 at 15:39 UTC

    Let me address the "printing array reference" part of your message, as I could not make sense of the remainder yet. "$dub_key => $dub_values\n" could be made to work by using:

    "$dub_key => ", join(",",@$dub_values), "\n" # will print # dubhpr01.hpux => name,uid,gid,comments
    or, with a Perl data dumping module, like Data::Dump:
    use Data::Dump; # somewhere before in the code # then "$dub_key => ", Data:Dump::dump($dub_values), "\n" # will print # dubhpr01.hpux => ["name", "uid", "gid", "comments"]
    (In the examples above, $dub_key = 'dubhpr01.hpux' and $dub_values = [qw(name uid gid comments)].)
Re: printing array reference and storing this data in a hash.
by shmem (Chancellor) on Dec 19, 2006 at 16:31 UTC

    ++++ for line numbers in your code, -- for the mess in the intro, makes ++ ;-)

    Answer to your first question: change line 27 to

    print $dub_key,Dumper($dub_values);

    More critics:

    • Line 0: I guess you forgot to use Data::Dumper;
    • Line 16: better write
      or die "dublin file '$element' did not open: $!\n"
      so you see what fubar the $element is
    • Line 19: better write
      $dub_values = (split /:/,<FILE>) [0]
      if you want just the first element from split; if you want an anonymous array, write
      $dub_values = [ split /:/,<FILE> ]
    • Lines 21-23: weird usage of Data::Dumper

    hth,
    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      OK understood and thank you! It is working now. quick question though...I read perldoc -f split and it made no mention of LIMIT in brackets in split /PATTERN/,EXPR,LIMIT Is this a trick? I know that it is spliting by fields like awk '{print $3}' /etc/passwd, but can anymore provide more detail? thank you
        The brackets are an anonymous array constructor. See perlref.
        $var = [ split /:/, $_ ];

        means "make an anonymous array (an array reference) and insert into it the results of the split operation; then assign the reference to the variable $var".

        More about split:

        $_ = "Fracassus Cacus Eryx Anteus"; # see Acme::MetaSyntactic $foo = split; # '4' $foo = split /\s+/, $_; # '4' ($foo) = split /\s+/, $_; # ('Fracassus') ($foo, $bar) = split /\s+/, $_; # ('Fracassus', 'Cacus') ($foo, $bar) = split /\s+/, $_, 2; # ('Fracassus', 'Cacus Eryx An +teus') ($foo, $bar) = split /\s+/, $_, 1; # ('Fracassus Cacus Eryx Anteu +s', '') ($foo) = split /\s+/, $_, 1; # ('Fracassus') ($foo) = (split /\s+/, $_,) [2]; # ('Eryx')

        It's odd that a split with LIMIT 1 behaves different when assigning to a list with a single or two variables; but it does. That's why I prefer to say

        $foo = (split /\s+/, $_) [0];

        if I want just the first element of the resulting list. The (split)[0] thingy means "give me the element 0 of the list returned by split".

        Thanks to BooK++ for Acme::MetaSyntactic

        --shmem

        update: added missing backslashes to /s+/ :~}

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
        I'll admit I just skimmed a bit, but can't find what you're talking about. Are you talking about shmem's solution for your line 19 similar to:
        $foo = ( split /pattern/, $string ) [ number ];
        ??? If that's the case, then look very carefully and you'll realize that the bracketed portion is not the optional third parameter to split(). The construct:
        ( returns_a_list )[ index ]
        or
        ( returns_a_list )[ index, index ]
        is called an array slice (or list slice). The indexes are the only ones from the list/array that end up being returned. The parentheses are there basically to bind the index to the whole list that's being returned.

        List slices are a very handy idiom, and can be used to great effect in Perl.

        Like lots of conveniences in Perl or any other higher-level dynamic language, this can also be abused since there are sometimes much more efficient solutions. Learning when to use slices and when to avoid generating the whole list to use just part of it is a classic machine time/programmer time trade-off. I always try to err on the side of saving programmer time until I actually need to worry about a specific hotspot in a program.


        Christopher E. Stith
Re: printing array reference and storing this data in a hash.
by philcrow (Priest) on Dec 19, 2006 at 15:30 UTC
    Since you have an array reference, you must dereference:
    @{ $dub_values }
    Phil