Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Problem de-referencing a variable

by Anonymous Monk
on Feb 09, 2009 at 20:26 UTC ( [id://742569]=perlquestion: print w/replies, xml ) Need Help??

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

Reverred Monks,
I have the following problem I do not know how to solve. Maybe it's just a syntax issue, but I can't figure it out. I need to interpret the output from a application that consists in a list of vectors with 20 numbers each. I know how to interpret this because originally, I had to code similar input to feed to the application in the first place. A partial table is given below as a hash of arrays (normally it would be in an external file I would read in with "do 'myfile.txt'"). I can reverse a hash all right - I found the perl function for that. But when I do, the keys of the new hash are now arrays. Perl knows that all right - if I print the keys, it prints something like:
ARRAY(0x33b930) ARRAY(0x889eb0) ARRAY(0x8896b4) ARRAY(0x33b810)
So how do I now get access to what those arrays actually contain? E.g., how do I get:
[ 1, 1, 1, 0, 1, 1, ], [ 1, 1, 1, 1, 0, 1, ], [ 1, 1, 0, 0, 0, 0, ], [ 0, 0, 1, 1, 1, 1, ],
Whenever I try, perl says the following:

Can't use string ("ARRAY(0x81e4c4)") as an ARRAY ref while "strict refs" in use at ./beispiel.plx line 36.

Any ideas? Am I going to have to try a completely different approach or is there a syntax for this?
#!/usr/bin/perl # Input: A file containing vectors of 20 numbers, like: # 1,1,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0 # 0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0 # Desired Output (see translation table below) # Odp- # kIr+ use strict; use warnings; my %translation = ( "i" => [ 1, 1, 1, 1, 1, 1, ], "I" => [ 1, 1, 0, 0, 1, 1, ], "o" => [ 1, 1, 1, 0, 1, 1, ], "u" => [ 1, 1, 1, 1, 0, 1, ], "O" => [ 1, 1, 0, 0, 0, 0, ], "p" => [ 0, 0, 1, 1, 1, 1, ], "d" => [ 0, 1, 1, 1, 1, 0, ], "k" => [ 0, 0, 1, 1, 0, 0, ], "f" => [ 0, 0, 1, 0, 1, 1, ], "s" => [ 0, 0, 1, 0, 0, 1, ], "r" => [ 0, 1, 0, 1, 0, 1, ], "/" => [ 0, 1, ], "+" => [ 1, 0, ], "*" => [ 1, 1, ], "-" => [ 0, 0, ], ); my %reverse_translation = reverse %translation; foreach my $key (keys %reverse_translation) { print STDERR $key . "\n"; # my @array = @{ $key }; # print join ",", @array; # print "\n"; }

Replies are listed 'Best First'.
Re: Problem de-referencing a variable
by jwkrahn (Abbot) on Feb 09, 2009 at 20:40 UTC
    my %reverse_translation = reverse %translation;

    That won't work because the array references are converted to strings when they are stored as hash keys and once they are strings they cannot be converted back to array references.   You probably need to do something like this:

    while ( my ( $key, $val ) = each %translation ) { print STDERR "$key\n"; # print join( ",", @$val ), "\n"; }
Re: Problem de-referencing a variable
by ikegami (Patriarch) on Feb 09, 2009 at 20:31 UTC
    my @array = @{ $key }; print join ",", @array;

    should be

    my @array = @{ $reverse_translation{key} }; print join ",", @array;

    But that wastefully copies the array. Just work with the array reference:

    my $array = $reverse_translation{key}; print join ",", @$array;

    Update: Oops, I missed the fact that you reversed the keys and values.

    While the above does solve a problem, you are also running afoul of the restriction that hash keys (for untied hashes) can only be strings. When you attempted to use an array reference as a key, a string representation of the array reference was used as the key rather than the array reference itself. So when you tried to deference the keys, you were trying to dereference a string.

    What are you trying to accomplish by reversing the hash? Would the following do?

    foreach my $key (keys %translation) { print("$key: "); print(join(",", @{ $translation{$key} })); print("\n"); }
Re: Problem de-referencing a variable
by Not_a_Number (Prior) on Feb 09, 2009 at 21:49 UTC

    I think you might have an XY Problem here.

    Correct me if I'm wrong, but I think that what you really want to do is to munge this input:

    1,1,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0 0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0

    using your %translation hash, to produce this output:

    Odp- kIr+

    This implies that each 20-character-long line in your input file may be divided into four segments, of respectively 6 + 6 + 6 + 2 bytes (counting from left to right).

    In which case, why not simplify matter by stringifying the 'segments' in question? Your %reverse_translation could then look like this:

    ( 110011 => 'I', 111101 => 'u', 11 => '*', 01 => '/', ... etc ..., )

    Here's a possible implementation, which works at least with the (rather sparse) data you provide:

    my %translation = ( # as in OP ); my %reverse_translation; for ( keys %translation ) { my $bin = join '', @{ $translation{$_}} ; $reverse_translation{$bin} = $_; } while ( <DATA> ) { my @segments = unpack 'A6A6A6A2', join '', split /,/; print $reverse_translation{$_} for @segments; print "\n"; } __DATA__ 1,1,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0 0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2024-04-19 08:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found