Get Perl to print full "key path" to values (Data::Dumper won't) - perl

$foo{alongkeyname}{anotherlongkeyname}{yetanotherlongkeyname}{afairlyshortkeynamewellitgotlongwhileiwastypingitsoiguessnot}{bob}{something} = 1;
How do I get Perl to print $foo and show me the full "path name" to
get to 1? In other words, I want output that looks similar to the
input above.
Data::Dumper won't do this, and the long key names wrap the output,
making even the indented form less useful.
Ages ago, I wrote my own "unfold" subroutine at https://github.com/barrycarter/bcapps/blob/master/bclib.pl#L109 which outputs:
<hash HASH(0x92a33a4)>
<key>
alongkeyname
</key>
<val>
<hash HASH(0x95103b4)>
<key>
anotherlongkeyname
</key>
<val>
<hash HASH(0x9510464)>
<key>
yetanotherlongkeyname
</key>
<val>
<hash HASH(0x9510434)>
<key>
afairlyshortkeynamewellitgotlongwhileiwastypingitsoiguessnot
</key>
<val>
<hash HASH(0x95bae7c)>
<key>
bob
</key>
<val>
<hash HASH(0x95cf8bc)>
something: 1
</hash HASH(0x95cf8bc)>
</val>
</hash HASH(0x95bae7c)>
</val>
</hash HASH(0x9510434)>
</val>
</hash HASH(0x9510464)>
</val>
</hash HASH(0x95103b4)>
</val>
</hash HASH(0x92a33a4)>
but that's not really useful either.
Real-life project inspiring this question: pulling SYNOP/BUOY data from the
XML::Simple hashified output of metaf2xml
EDIT: Thank you Ben! I tried this and it worked great on my example. Then I tried it on another hash, and got:
$VAR1 = {'remark' => [{'obsStationType' => {'stationType' => {'v' => 'AO2'},'s' => 'AO2'}},{'needMaint' => {'s' => '$'}}],'QNH' => {'inHg' => {'v' => '29.99'},'s' => 'A2999'},'visPrev' => {'distance' => {'u' => 'SM','v' => '7','rp' => '1'},'s' => '7SM'},'sfcWind' => {'wind' => {'speed' => {'u' => 'KT','v' => '3'},'dir' => {'rn' => '5','v' => '60','rp' => '4'}},'measurePeriod' => {'u' => 'MIN','v' => '2'},'s' => '06003KT'},'obsStationId' => {'id' => {'v' => 'KBTR'},'s' => 'KBTR'},'obsTime' => {'s' => '080940Z','timeAt' => {'hour' => {'v' => '09'},'minute' => {'v' => '40'},'day' => {'v' => '08'}}},'s' => 'KBTR 080940Z 06003KT 7SM SCT003 BKN200 24/23 A2999 RMK AO2 $','cloud' => [{'cloudCover' => {'v' => 'SCT'},'s' => 'SCT003','cloudBase' => {'u' => 'FT','v' => '300'}},{'cloudCover' => {'v' => 'BKN'},'s' => 'BKN200','cloudBase' => {'u' => 'FT','v' => '20000'}}],'temperature' => {'relHumid4' => {'v' => '94.15'},'dewpoint' => {'temp' => {'u' => 'C','v' => '23'}},'relHumid3' => {'v' => '94.03'},'relHumid1' => {'v' => '94.16'},'relHumid2' => {'v' => '94.17'},'air' => {'temp' => {'u' => 'C','v' => '24'}},'s' => '24/23'}};
So the question I think I want to answer is: what value of this hash will give me the "94.15" you see above? It's sort of hard to tell from the above.
(If anyone's curious, the answer is $hash{temperature}{relHumid4}{v})
MORE EDIT: Thanks, Ilmari. I tried dump_var($VAR1) w/ my VAR1 above and got...
HASH(0x9ae6764) = undef;
I also tried dump_var({$VAR1}) with the same result. I might've missed something. Could you cut and paste my VAR1 above and see if it works? I did export 'Dumper' as you indicate in your 'use' statement.

Here's a quick do-it-yourself solution:
use Data::Dumper 'Dumper';
sub dump_var {
my ($prefix, $var) = #_;
my #rv;
local $Data::Dumper::Indent = 0;
local $Data::Dumper::Terse = 1;
if (ref $var eq 'ARRAY' and #$var) {
for my $i (0 .. $#$var) {
push #rv, dump_var($prefix . "->[$i]", $var->[$i]);
}
} elsif (ref $var eq 'HASH' and %$var) {
foreach my $key (sort keys %$var) {
push #rv, dump_var($prefix . '->{'.Dumper($key).'}', $var->{$key});
}
} elsif (ref $var eq 'SCALAR') {
push #rv, dump_var('${' . $prefix . '}', $$var);
} else {
push #rv, "$prefix = " . Dumper($var) . ";\n";
}
return #rv;
}
and some test code:
my $foo = {
alpha => [ 'beta', \ 'gamma' ],
one => { two => { three => 3, four => 3.141 },
five => { six => undef, seven => \*STDIN },
},
foobar => sub { print "Hello, world!\n"; },
};
print dump_var('$foo' => $foo);
which produces the output:
$foo->{'alpha'}->[0] = 'beta';
${$foo->{'alpha'}->[1]} = 'gamma';
$foo->{'foobar'} = sub { "DUMMY" };
$foo->{'one'}->{'five'}->{'seven'} = \*::STDIN;
$foo->{'one'}->{'five'}->{'six'} = undef;
$foo->{'one'}->{'two'}->{'four'} = '3.141';
$foo->{'one'}->{'two'}->{'three'} = 3;
Edit: While testing a PHP version of this code, I realized that it didn't correctly handle empty arrays and hashes. I've fixed the code so that such values are passed directly to Dumper.

Data::Dumper can print output similar to what you're looking for by setting Indent to 0.
[ben#imac ~]$ perl
use Data::Dumper;
$Data::Dumper::Indent = 0;
$foo{alongkeyname}{anotherlongkeyname}{yetanotherlongkeyname}{afairlyshortkeynamewellitgotlongwhileiwastypingitsoiguessnot}{bob}{something} = 1;
print Dumper(\%foo);
Output:
$VAR1 = {'alongkeyname' => {'anotherlongkeyname' => {'yetanotherlongkeyname' => {'afairlyshortkeynamewellitgotlongwhileiwastypingitsoiguessnot' => {'bob' => {'something' => 1}}}}}};

For a possible solution to the problem behind your question, please see the feature announced today in the Project News for metaf2xml.

Related

Perl push values in a hash

I am always confusing or don't know how to handle hash in perl.
So here is the problem,
Considering the whole thing, i am trying to change the key name in the below hash.
my %hash_new = {
'customername' => 'Lee & toys',
'employee_name' => 'Checngwang',
'customer_id' => 'X82349K',
'customer_address' => 'classic denver ranch, meadows drive',
'types' => 'category la',
};
my %selectCols = ('customername' => 'CUSTOMERNAME','employee_name' => 'EMP_NAME','customer_id' => 'cusid','customer_address' => 'cusaddr','types' => 'Typs');
my %new_hash = ();
foreach my $hash_keys (keys %hash_new){
my $newKey = $selectCols{$hash_keys};
$new_hash{$newKey} = $hash_new{$hash_keys};
}
print Dumper %new_hash;
Output of %new_hash is something like a key value combination of continuous string as below,
CUTOMERNAMELee & toysEMP_NAMEChecngwangcus_idX82349Kcusaddrclassic denver ranch, meadows driveTypscategory la
But instead of this, i need the hash like,
$VAR1 = {
'CUSTOMERNAME' => 'Lee & toys',
'EMP_NAME' => 'Checngwang',
'cusid' => 'X82349K',
'cusaddr' => 'classic denver ranch, meadows drive',
'Typs' => 'category la',
};
Please help me around this!
If I understood you correctly, then this works:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash_new = (
'customername' => 'Lee & toys',
'employee_name' => 'Checngwang',
'customer_id' => 'X82349K',
'customer_address' => 'classic denver ranch, meadows drive',
'types' => 'category la'
);
my %selectCols = (
'customername' => 'CUSTOMERNAME',
'employee_name' => 'EMP_NAME',
'customer_id' => 'cusid',
'customer_address' => 'cusaddr',
'types' => 'Typs'
);
my %new_hash = ();
foreach my $hash_keys (keys %hash_new){
my $newKey = $selectCols{$hash_keys};
$new_hash{$newKey} = $hash_new{$hash_keys};
}
print Dumper \%new_hash;
The only code I changed in your code was using () instead of {} in %hash_new and escaped the % in the Dumper statement. The % should be escaped because Dumper expects a reference, not a hash (that's true also for all other Perl variable types in use with Dumper).
Output:
$VAR1 = {
'Typs' => 'category la',
'cusaddr' => 'classic denver ranch, meadows drive',
'EMP_NAME' => 'Checngwang',
'cusid' => 'X82349K',
'CUSTOMERNAME' => 'Lee & toys'
};
Also, don't use confusing names like %hash_new and %new_hash. It's - well - confusing.

Odd number of elements in Perl hash

I'm having some trouble with hashes. I need to get a list of version with key => value pairs into a hash but kept getting an error. The code just below is my recent attempt. Some of the strings have been changed and unneeded code isn't included.
I've looked all over the net but haven't been able to find anything that can help me. I've used Perl for a long time but haven't used hashes and arrays much. Most of my Perl experience has had to do with regex and shell execution. If I was using PHP, I would just use a multidimensional array but this is Perl and there's a lot more to the script I'm writing than what is shown or I'd switch to PHP.
I appreciate whoever takes the time to help. Thanks!
sub sub1 {
# Read file which populates #rows with each line.
my %data;
for (my $i=2; $i <= scalar #rows - 1; $i++) {
$ver =~ s/\s//m;
$data{ $ver } = [
'version', $ver,
'available', $table_tree->cell($jt,1)->as_text,
'bsupport', $table_tree->cell($jt,2)->as_text,
'ssupport', $table_tree->cell($jt,3)->as_text,
'eol', $table_tree->cell($jt,3)->as_text,
'utype', $table_tree->cell($jt,5)->as_text,
'lreleases', $table_tree->cell($jt,7)->as_text
];
};
return %data;
}
sub check_ {
# line 199 follows
my (%hash) = #_;
print Dumper (\%hash)."\n";
}
my %data = sub1($file);
check_(%data);
Warning:
Odd number of elements in hash assignment at ./file.pl line 199 (#1)
(W misc) You specified an odd number of elements to initialize a hash,
which is odd, because hashes come in key/value pairs.
The %hash when dumped is:
$VAR1 = {
'string1' => [
'version',
'string1',
'available',
'stringa',
'bsupport',
'stringb',
'ssupport',
'stringc',
'eol',
'stringd',
'utype',
'stringe',
'lreleases',
'stringf'
],
'string2' => [
'version',
'string2',
'available',
'stringa',
'bsupport',
'stringb',
'ssupport',
'stringc',
'eol',
'stringd',
'utype',
'stringe',
'lreleases',
'stringf'
],
'string3' => [
'version',
'string3',
'available',
'stringa',
'bsupport',
'stringb',
'ssupport',
'stringc',
'eol',
'stringd',
'utype',
'stringe',
'lreleases',
'stringf'
],
# ...
}
I was originally trying to have my has be as follows. Where $VAR1 = { 'stringN' => { ... } would be any number with any number of key => value pairs but would also get the same error. I had it working but it would always generate the error.
$VAR1 = {
'string1' => {
'version' => 'string1',
'available' => 'stringa',
'bsupport' => 'stringb',
'ssupport' => 'stringc',
'eol' => 'stringd',
'utype' => 'stringe',
'lreleases' => 'stringf'
},
'string2' => {
'version' => 'string2',
'available' => 'stringa',
'bsupport' => 'stringb',
'ssupport' => 'stringc',
'eol' => 'stringd',
'utype' => 'stringe',
'lreleases' => 'stringf'
},
'string3' => {
'version' => 'string3',
'available' => 'stringa',
'bsupport' => 'stringb',
'ssupport' => 'stringc',
'eol' => 'stringd',
'utype' => 'stringe',
'lreleases' => 'stringf'
}
# ...
}
It's because you're using [ which is the anonymous array constructor. Try using { instead.
And it might be a bit more idiomatic if you did:
$data{ $ver } = {
version => $jver,
available => $table_tree->cell($jt,1)->as_text,
};
Oh, and indent your code. That for loop doesn't finish where you (might!) think it does. Especially - check where the return happens. (And what $jt is set to - it appears unrelated to $i)

Converting a multi dimensional hash to a csv

I have a multidimensional hash, that i am printing on the screen, i want to convert the hash to a CSV formatted data.
Sample output of my script
$VAR1 = {
'1' => {
'EVENT_NAME' => '"x1"',
'NV_MANAGED_OBJECT_INSTANCE' => '"SubNetwork=ONRM_RootMo,SubNetwork=AXE,ManagedElement=WBSC1,BssFunction=BSS_ManagedFunction,BtsSiteMgr=WV5619"',
'EVENT_TYPE' => '"x5"',
'NV_MANAGED_OBJECT_CLASS' => '"BtsSiteMgr"',
'AdditionalText_Line03' => '"MO RSITE ALARM SLOGAN"',
'NV_SPECIFIC_PROBLEM' => '"RADIO X-CEIVER ADMINISTRATION MANAGED OBJECT FAULT"',
'ResynchEvent' => '"false"',
'SubNetwork' => '"ONRM_RootMo"',
'SubNetwork_0' => '"ONRM_RootMo"',
'NV_PROBABLE_CAUSE' => '"0"',
'AdditionalText_Line04' => '"RXOCF-87 WV5619 BTS EXTERNAL"',
'RawCaptureTimeStamp' => '1449806147',
'BssFunction' => '"BSS_ManagedFunction"',
'DOMAIN_NAME' => '"ALARM_IRP_VERSION_1_1"',
'AdditionalText_Line02' => '"MANAGED OBJECT FAULT"',
'NV_PROPOSED_REPAIR_ACTIONS' => '""',
'NV_ACK_TIME' => '"12/11/15 4:55:45 AM"',
'AdditionalText_Line01' => '"RADIO X-CEIVER ADMINISTRATION"',
'NV_ACK_STATE' => '"2"',
'NV_SYSTEM_DN' => '"Ericsson OSS IRPAgent"',
'ManagedElement' => '"WBSC1"',
'SubNetwork_1' => '"AXE"',
'BtsSiteMgr' => '"WV5619"',
'NV_EVENT_TIME' => '"12/11/15 4:55:00 AM"',
'AdditionalText_Line06' => '"-ProbableCause(OSS)=Different causes possible for same message"',
'AdditionalText_LineCount' => '"7"',
'AdditionalText_Line05' => '"END"',
'AdditionalText_Line00' => '"*** ALARM 505 A3/APT \\"WBSC1/G14B/04/0\\"U 151211 0455"',
'NV_ADDITIONAL_TEXT' => '"*** ALARM 505 A3/APT \\"WBSC1/G14B/04/0\\"U 151211 0455\\nRADIO X-CEIVER ADMINISTRATION\\nMANAGED OBJECT FAULT\\n\\nMO RSITE ALARM SLOGAN\\nRXOCF-87 WV5619 BTS EXTERNAL\\n\\nEND\\n-ProbableCause(OSS)=Different causes possible for same message"',
'NV_NOTIFICATION_ID' => '"2267705"',
'AdditionalText_Line07' => '"-ProbableCause(OSS)=Different causes possible for same message"',
'NV_ACK_USER_ID' => '""',
'NV_ALARM_ID' => '"55079020"',
'NV_PERCEIVED_SEVERITY' => '"4"'
},
'0' => {
'EVENT_NAME' => '"x4"',
'NV_MANAGED_OBJECT_INSTANCE' => '"SubNetwork=ONRM_RootMo,SubNetwork=AXE,ManagedElement=WBSC1,BssFunction=BSS_ManagedFunction,BtsSiteMgr=WV5619"',
'EVENT_TYPE' => '"x5"',
'NV_MANAGED_OBJECT_CLASS' => '"BtsSiteMgr"',
'AdditionalText_Line03' => '"MO RSITE ALARM SLOGAN"',
'NV_SPECIFIC_PROBLEM' => '"RADIO X-CEIVER ADMINISTRATION MANAGED OBJECT FAULT"',
'ResynchEvent' => '"false"',
'SubNetwork' => '"ONRM_RootMo"',
'SubNetwork_0' => '"ONRM_RootMo"',
'NV_PROBABLE_CAUSE' => '"0"',
'AdditionalText_Line04' => '"RXOCF-87 WV5619 BTS EXTERNAL"',
'RawCaptureTimeStamp' => '1449806146',
'BssFunction' => '"BSS_ManagedFunction"',
'DOMAIN_NAME' => '"ALARM_IRP_VERSION_1_1"',
'AdditionalText_Line02' => '"MANAGED OBJECT FAULT"',
'NV_PROPOSED_REPAIR_ACTIONS' => '""',
'NV_ACK_TIME' => '"12/11/15 4:55:45 AM"',
'AdditionalText_Line01' => '"RADIO X-CEIVER ADMINISTRATION"',
'NV_ACK_STATE' => '"2"',
'NV_SYSTEM_DN' => '"IRPAgent"',
'ManagedElement' => '"WBSC1"',
'SubNetwork_1' => '"AXE"',
' Status_TicketType' => '0',
'BtsSiteMgr' => '"WV5619"',
'NV_EVENT_TIME' => '"12/11/15 4:55:00 AM"',
'AdditionalText_Line06' => '"-ProbableCause(OSS)=Different causes possible for same message"',
'AdditionalText_LineCount' => '"7"',
'AdditionalText_Line05' => '"END"',
'AdditionalText_Line00' => '"*** ALARM 504 A3/APT \\"WBSC1/G14B/04/0\\"U 151211 0451"',
'NV_ADDITIONAL_TEXT' => '"*** ALARM 504 A3/APT \\"WBSC1/G14B/04/0\\"U 151211 0451\\nRADIO X-CEIVER ADMINISTRATION\\nMANAGED OBJECT FAULT\\n\\nMO RSITE ALARM SLOGAN\\nRXOCF-87 WV5619 BTS EXTERNAL\\n\\nEND\\n-ProbableCause(OSS)=Different causes possible for same message"',
'NV_NOTIFICATION_ID' => '"2267704"',
'NV_ACK_USER_ID' => '""',
'NV_ALARM_ID' => '"55079016"',
'NV_PERCEIVED_SEVERITY' => '"6"'
}
};
Code responsible for traversing the file into a hash:
my $i=0;
open my $cap1, $file or die "Could not open $file: $!";
while( my $line = <$cap1>) {
my #pairs;
my $name;
my $value;
if($line ne ''){
#pairs = split / = /, $line;
$name = $pairs[0];
chomp($name);
$value = $pairs[1];
chomp($value);
}
if($name ne '' && $name !~ /^Status_/){
$data{$i}{$name} = $value;
}
if($name =~ /^RawCaptureTimeStamp/){
$i++;
}
}
print Dumper \%data;
Heads up: The columns in each set of the hash is not fixed. it is dynamic.
However, i have got all possible column names in another array. So you can assume i have all columns (EVENT_NAME,EVENT_TYPE,...) in an array file. Using that i need to convert the existing hash into a CSV.
Found the solution myself:
foreach my $j (sort keys %data) {
foreach (#uniqueNames) {
if(exists($data{$j}{$_})){
print "$data{$j}{$_},";
}
else{
print "\"\"",;
}
}
print "\n";
}
Where #uniqueNames is an array having all possible unique columns from the original hash table.

Data::Dumper::Freezer proper usage

I'm trying to log data structures in an old and big Perl project. In order to do so, I use Data::Dumper, however, some structures are a bit too large and spam the log. So I'm looking for a way to log them in a less verbose manner.
Now Dumper's doc mentions $Data::Dumper::Freezer = <method_name> variable that can be used to fix that. I've tried using that.
Adding a serializer method that returns "shortened" value results in nothing, though the method gets called. Making the serializer method act on $_[0] causes the needed effect, but spoils the original data structure.
I'm confused. What am I doing wrong? How can I fix it?
Here's a refined sample code:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Indent = 0;
$\="\n";
my $x = Foo->new ( answer => 42, use => "force" );
my $y = { foo => $x };
print "initial plain:\n\t", Dumper( $x );
print "initial compound:\n\t", Dumper( $y );
{
local $Data::Dumper::Freezer = 'freeze_pure';
print "still not abbreviated data:\n\t", Dumper( $y );
};
{
local $Data::Dumper::Freezer = 'freeze_replace';
print "abbreviated data:\n\t", Dumper( $y );
};
print "initial data is still intact:\n\t", Dumper( $x );
print "compound data is corrupted:\n\t", Dumper( $y );
package Foo;
sub new {
my $class = shift;
return bless { #_ }, $class;
};
sub freeze_pure {
my $self = $_[0];
warn "# In freeze_pure";
return bless {
values => join ",", values %$self
}, (ref $self) . "::short";
};
sub freeze_replace {
my $self = $_[0];
warn "# In freeze_replace";
$_[0] = bless {
values => join ",", values %$self
}, (ref $self) . "::short";
return;
};
And output:
initial plain:
$VAR1 = bless( {'use' => 'force','answer' => 42}, 'Foo' );
initial compound:
$VAR1 = {'foo' => bless( {'use' => 'force','answer' => 42}, 'Foo' )};
# In freeze_pure at dumper-freezer.pl line 36.
still not abbreviated data:
$VAR1 = {'foo' => bless( {'use' => 'force','answer' => 42}, 'Foo' )};
# In freeze_replace at dumper-freezer.pl line 42.
abbreviated data:
$VAR1 = {'foo' => bless( {'values' => 'force,42'}, 'Foo::short' )};
initial data is still intact:
$VAR1 = bless( {'use' => 'force','answer' => 42}, 'Foo' );
compound data is corrupted:
$VAR1 = {'foo' => bless( {'values' => 'force,42'}, 'Foo::short' )};
Although the documentation is a bit sparse, the intended use of freezer/toaster is data serialization/de-serialization, not prettification of debugging output.
So, Data::Dumper calls the freezer method, but doesn't use the return value. The idea is probably that if you're going to serialize an object, you won't be messing with it again until you de-serialize it, so there's no problem with changing the object itself.
Here's the relevant section of code from the Data::Dumper source:
# Call the freezer method if it's specified and the object has the
# method. Trap errors and warn() instead of die()ing, like the XS
# implementation.
my $freezer = $s->{freezer};
if ($freezer and UNIVERSAL::can($val, $freezer)) {
eval { $val->$freezer() };
warn "WARNING(Freezer method call failed): $#" if $#;
}
If you just want to reduce the size of the output in your logs, you can remove newlines and indentation by setting $Data::Dumper::Indent to zero:
use Data::Dumper;
use WWW::Mechanize;
$Data::Dumper::Indent = 0;
my $mech = WWW::Mechanize->new;
print Dumper $mech;
Output:
$VAR1 = bless( {'headers' => {},'ssl_opts' => {'verify_hostname' => 1},'forms' => undef,'page_stack' => [],'text' => undef,'requests_redirectable' => ['GET','HEAD','POST'],'timeout' => 180,'onerror' => sub { "DUMMY" },'current_form' => undef,'links' => undef,'max_redirect' => 7,'quiet' => 0,'images' => undef,'noproxy' => 0,'stack_depth' => 8675309,'show_progress' => undef,'protocols_forbidden' => undef,'no_proxy' => [],'handlers' => {'request_prepare' => bless( [{'owner' => 'LWP::UserAgent::cookie_jar','callback' => sub { "DUMMY" },'line' => '/home/foo/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/LWP/UserAgent.pm:705'}], 'HTTP::Config' ),'response_header' => bless( [{'owner' => 'LWP::UserAgent::parse_head','callback' => sub { "DUMMY" },'m_media_type' => 'html','line' => '/home/foo/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/LWP/UserAgent.pm:684'}], 'HTTP::Config' ),'response_done' => bless( [{'owner' => 'LWP::UserAgent::cookie_jar','callback' => sub { "DUMMY" },'line' => '/home/foo/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/LWP/UserAgent.pm:708'}], 'HTTP::Config' )},'onwarn' => sub { "DUMMY" },'protocols_allowed' => undef,'use_eval' => 1,'local_address' => undef,'autocheck' => 1,'title' => undef,'def_headers' => bless( {'user-agent' => 'WWW-Mechanize/1.75'}, 'HTTP::Headers' ),'cookie_jar' => bless( {'COOKIES' => {}}, 'HTTP::Cookies' ),'proxy' => {},'max_size' => undef}, 'WWW::Mechanize' );
This is still a lot of output, but it's certainly more compact than:
$VAR1 = bless( {
'headers' => {},
'ssl_opts' => {
'verify_hostname' => 1
},
'forms' => undef,
'page_stack' => [],
'text' => undef,
'requests_redirectable' => [
'GET',
'HEAD',
'POST'
],
'timeout' => 180,
'onerror' => sub { "DUMMY" },
'current_form' => undef,
'links' => undef,
'max_redirect' => 7,
'quiet' => 0,
'images' => undef,
'noproxy' => 0,
'stack_depth' => 8675309,
'show_progress' => undef,
'protocols_forbidden' => undef,
'no_proxy' => [],
'handlers' => {
'request_prepare' => bless( [
{
'owner' => 'LWP::UserAgent::cookie_jar',
'callback' => sub { "DUMMY" },
'line' => '/home/foo/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/LWP/UserAgent.pm:705'
}
], 'HTTP::Config' ),
'response_header' => bless( [
{
'owner' => 'LWP::UserAgent::parse_head',
'callback' => sub { "DUMMY" },
'm_media_type' => 'html',
'line' => '/home/foo/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/LWP/UserAgent.pm:684'
}
], 'HTTP::Config' ),
'response_done' => bless( [
{
'owner' => 'LWP::UserAgent::cookie_jar',
'callback' => sub { "DUMMY" },
'line' => '/home/foo/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/LWP/UserAgent.pm:708'
}
], 'HTTP::Config' )
},
'onwarn' => sub { "DUMMY" },
'protocols_allowed' => undef,
'use_eval' => 1,
'local_address' => undef,
'autocheck' => 1,
'title' => undef,
'def_headers' => bless( {
'user-agent' => 'WWW-Mechanize/1.75'
}, 'HTTP::Headers' ),
'cookie_jar' => bless( {
'COOKIES' => {}
}, 'HTTP::Cookies' ),
'proxy' => {},
'max_size' => undef
}, 'WWW::Mechanize' );
Alternatively, you could try Data::Dump, which allows you to filter the output using Data::Dump::Filtered. I prefer Data::Dump to Data::Dumper anyway because I think it has more sensible defaults (e.g. outputting escape sequences for whitespace other than spaces).
I haven't used the filtering feature yet, but brian d foy wrote a nice article about it with several examples.

Perl Hash Array foreach issue

I have a response which is displayed through Data::Dumper - Dumper($cat_response->result->{'categories'})
$VAR1 = { 'literature' => '1120', 'law' => '1153', 'arts and crafts' => '1132', 'children' => '1141', 'hobbies' => '1133', 'economy' => '1166', 'jobs' => '1140', 'media' => '1144', 'music' => '1147', 'animals' => '1170', 'business' => '1119', 'diet' => '1122', 'travel reviews' => '1154', 'jewelry' => '1157', 'movies' => '1146', 'television' => '1125', 'politics' => '1168', 'internet' => '1139', 'history' => '1129', 'recipes' => '1156', 'press releases' => '1151', 'presents' => '1128', 'marketing' => '1143', 'translations' => '1162', 'fashion' => '1145', 'technology' => '1163', 'real estate' => '1138', 'computer' => '1173', 'automobile' => '1116', 'finances' => '1126', 'weddings' => '1134', 'games' => '1127', 'esoterism' => '1124', 'horoscopes' => '1135', 'shopping' => '1123', 'humor' => '1137', 'miscellaneous' => '1159', 'science' => '1167', 'programming' => '1152', 'languages' => '1161', 'beauty' => '1117', 'sports' => '1160', 'hotels' => '1136', 'plants' => '1149', 'education' => '1118', 'traveling' => '1155', 'health' => '1130', 'telecommunication' => '1164', 'environment' => '1171', 'software' => '1158', 'sweepstakes' => '1131', 'logistics' => '1142', 'home and family' => '1169', 'news' => '1148' };
To access it, I use:
my %categories = $cat_response->result->{'categories'};
foreach my $cat (keys (%categories)) {
<option value="<% $categories{'$cat'} %>"><% $cat %></option>
}
However, the value of Dumper($cat) is: $VAR1 = 'HASH(0x7fe972641560)';
Did I miss something?
You missing use strict; use warnings; for one. (Well, either that, or you forgot to tell us that Perl told you about your problem.)
$cat_response->result->{'categories'} contains a reference to a hash. Makes no sense to assign that to a hash.
my $categories = $cat_response->result->{'categories'};
foreach my $cat (keys (%$categories)) {
<option value="<% $categories->{'$cat'} %>"><% $cat %></option>
}