Stuck trying to access hash value - perl

I inherited a script and I need to be able to access some data from a hash. I want to be able to access the MB_Path value from the following.
$VAR1 = bless(
{
'ME_Parts' => [
bless(
{
'ME_Bodyhandle' => bless(
{
'MB_Path' => '/tmp/msg-15072-1.txt'
},
'MIME::Body::File'
),
'ME_Parts' => [],
'mail_inet_head' => bless(
{
'mail_hdr_foldlen' => 79,
'mail_hdr_modify' => 0,
'mail_hdr_list' => [
'Content-Type: text/plain; charset="us-ascii"',
'Content-Transfer-Encoding: quoted-printable'
],
'mail_hdr_hash' => {
'Content-Type' => [
\$VAR1->{'ME_Parts'}[0]{'mail_inet_head'}
{'mail_hdr_list'}[0]
],
'Content-Transfer-Encoding' => [
\$VAR1->{'ME_Parts'}[0]{'mail_inet_head'}
{'mail_hdr_list'}[1]
]
},
'mail_hdr_mail_from' => 'KEEP',
'mail_hdr_lengths' => {}
},
'MIME::Head'
)
},
'MIME::Entity'
),
bless(
{
'ME_Bodyhandle' => bless(
{
'MB_Path' => '/tmp/msg-15072-2.html'
},
'MIME::Body::File'
),
'ME_Parts' => [],
'mail_inet_head' => bless(
{
'mail_hdr_foldlen' => 79,
'mail_hdr_modify' => 0,
'mail_hdr_list' => [
'Content-Type: text/html;charset="us-ascii"',
'Content-Transfer-Encoding: quoted-printable'
],
'mail_hdr_hash' => {
'Content-Type' => [
\$VAR1->{'ME_Parts'}[1]{'mail_inet_head'}
{'mail_hdr_list'}[0]
],
'Content-Transfer-Encoding' => [
\$VAR1->{'ME_Parts'}[1]{'mail_inet_head'}
{'mail_hdr_list'}[1]
]
},
'mail_hdr_mail_from' => 'KEEP',
'mail_hdr_lengths' => {}
},
'MIME::Head'
)
},
'MIME::Entity'
)
],
'ME_Epilogue' => [],
'ME_Preamble' => [],
'mail_inet_head' => bless(
{
'mail_hdr_foldlen' => 79,
'mail_hdr_modify' => 0,
'mail_hdr_list' => [
'Content-Type: multipart/alternative;boundary="----_=_NextPart_002_01CEB949.DC6B0180"'
],
'mail_hdr_hash' => {
'Content-Type' =>
[ \$VAR1->{'mail_inet_head'}{'mail_hdr_list'}[0] ]
},
'mail_hdr_mail_from' => 'KEEP',
'mail_hdr_lengths' => {}
},
'MIME::Head'
)
'MIME::Entity'
);
I thought I could simply do the following
print $ent->parts->($i)->{ME_Bodyhandle}->{MB_Path};
However when I do that I get and error that the value is not initialized. But when I do dump of just $ent->parts->($i) I get the above code.
I am just stuck on this one.
Thanks,
Leo C

You don't have a hash, you have an object (which happens to be implemented as a hash). That's why the Data::Dumper output keeps saying bless(...). You shouldn't be poking into its internals.
I think you're looking for
$ent->parts($i)->bodyhandle->path;

Until you have exhausted the possibilities of the documentation, there is no excuse for dumping the underlying data structure that represents a Perl object and hard-coding access to its components. The rules of encapsulation apply to Perl object-oriented programming just as much as any other language.
The documentation for
MIME::Entity
and
MIME::Body
is quite clear, and the code you need is something like this
for my $part ($ent->parts) {
my $path = $part->bodyhandle->path;
print $path, "\n";
}
output
/tmp/msg-15072-1.txt
/tmp/msg-15072-2.html

This:
print $ent->parts->($i)->{ME_Parts}->[$i]->{ME_Bodyhandle}->{MB_Path};

Related

Looking of a value in blessed hash

I am a begginer in Perl an i am trying to get à value from à blessed hash.
The value is ip adresses, i tried that with no success
print $vm->guest->ipStack->dnsConfig->ipAddress;
print $vm->guest->ipStack{dnsConfig}{ipAddress};
$VAR1 = [
bless( {
"ipRouteConfig" => bless( {
"ipRoute" => [
bless( {
"gateway" => bless( {
"device" => 0,
"ipAddress" => "10.*******"
}, 'NetIpRouteConfigInfoGateway' ),
"network" => "0.0.0.0",
"prefixLength" => 0
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"network" => "1***********",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' ),
"prefixLength" => 23
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 32,
"network" => "10**************",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' )
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 32,
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' ),
"network" => "1***********5"
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 4,
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' ),
"network" => "224.0.0.0"
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' ),
"network" => "255.255.255.255",
"prefixLength" => 32
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 64,
"network" => "fe80::",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' )
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 128,
"network" => "fe80::",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' )
}, 'NetIpRouteConfigInfoIpRoute' ),
bless( {
"prefixLength" => 8,
"network" => "ff00::",
"gateway" => bless( {
"device" => 0
}, 'NetIpRouteConfigInfoGateway' )
}, 'NetIpRouteConfigInfoIpRoute' )
]
}, 'NetIpRouteConfigInfo' ),
"dnsConfig" => bless( {
"dhcp" => 0,
"searchDomain" => [
"france"
],
"hostName" => "HOST",
"ipAddress" => [
"10.60****",
"10.6*****",
"10.8*****"
],
"domainName" => "france"
}, 'NetDnsConfigInfo' )
}, 'GuestStackInfo' )
]
Whatever you have dumped is an array, not a hash. You need to show the call to Dumper for us to help you properly
Also, since this is a structure of blessed objects, you should be using their methods to access information, not going by the "back door" and messing with the data structure directly. Unfortunately GuestStackInfo and NetDnsConfigInfo are VMware classes and not one of the standard Perl types so I can't suggest what method calls may be appropriate
Here are some notes
The structure referred to by $VAR1 is a one-element array containing a GuestStackInfo object
The GuestStackInfo object contains a NetIpRouteConfigInfo object and a NetDnsConfigInfo object. I assume you are interested in the latter as you say "The value is ip adresses", and the nearest hash key is ipAddress in the NetDnsConfigInfo object
The ipAddress element is reference to an array of IP address-like strings
To access this array you would write
my $addresses = $VAR1->[0]{dnsConfig}{ipAddress};
and then to print them all out, use
print "$_\n" for #$addresses;
But please take note of my initial comments -- you should be using method calls and not poking around the data structure like this. Is there any documentation for those classes?

Append an element to an already existing SOAP::Data complex type

I'm very new to SOAP, PERL and pretty much everything else I've been asked to do so I'm hoping someone can point me in the right direction.
I've implemented a simple WCF solution and I've written a PERL client which passes a "complex data structure" to the solution using SOAP::lite and SOAP::Data. All this works very well so far, WCF solution see's the array as an array and I'm able to iterate through the array on the server side just fine.
However, I'm having an issue trying to append a data element to the array on the PERL side. I have the following code, which builds the array I need, but I need to append a few lines to the array later on in the code and I can't figure out how to that.
# build array of values
my $data= SOAP::Data->new
(name => 'array', value =>
[
SOAP::Data->new(name => 'elem:string', value => 'firststring'),
SOAP::Data->new(name => 'elem:string', value => 'secondstring'),
SOAP::Data->new(name => 'elem:string', value => 'thridstring')
]
)
->attr
(
{ 'xmlns:elem' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays','xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance'}
);
# create a new element
my $elem1 = SOAP::Data->new(name => 'elem:string', value => 'addedstring');
# try to add the element
push(#{$data->{array}},$elem1);
#.... send, catch, print.. bla bla bla
The code I have runs, and the WCF service see's the array just fine, but the $elem1 value is never actually appended to the SOAP envelope.
Any help is GREATLY appreciated...
Take a look at what $data is using Data::Dumper, you get this
$VAR1 = bless( {
'_attr' => {
'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance',
'xmlns:elem' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
},
'_signature' => [],
'_name' => 'array',
'_value' => [
[
bless( {
'_value' => [
'firststring'
],
'_name' => 'string',
'_prefix' => 'elem',
'_signature' => [],
'_attr' => {}
}, 'SOAP::Data' ),
bless( {
'_value' => [
'secondstring'
],
'_name' => 'string',
'_signature' => [],
'_prefix' => 'elem',
'_attr' => {}
}, 'SOAP::Data' ),
bless( {
'_attr' => {},
'_value' => [
'thridstring'
],
'_name' => 'string',
'_signature' => [],
'_prefix' => 'elem'
}, 'SOAP::Data' )
]
]
}, 'SOAP::Data' );
There is no $data->{array}
A look at the documentation for SOAP::Data, says you should use $data->value to access the array you created.
push #{ $data->value }, $elem1;
print Dumper $data->value;
yields
$VAR1 = [
bless( {
'_attr' => {},
'_prefix' => 'elem',
'_value' => [
'firststring'
],
'_name' => 'string',
'_signature' => []
}, 'SOAP::Data' ),
bless( {
'_signature' => [],
'_name' => 'string',
'_value' => [
'secondstring'
],
'_prefix' => 'elem',
'_attr' => {}
}, 'SOAP::Data' ),
bless( {
'_name' => 'string',
'_signature' => [],
'_value' => [
'thridstring'
],
'_prefix' => 'elem',
'_attr' => {}
}, 'SOAP::Data' ),
bless( {
'_attr' => {},
'_prefix' => 'elem',
'_value' => [
'addedstring'
],
'_name' => 'string',
'_signature' => []
}, 'SOAP::Data' )
];
Thanks Gabs00,
push $data->value, $elem1; worked beautifully

LWP::UserAgent and proxy error

I have a proxy error when using LWP::UserAgent
this is the code:
my $ua = LWP::UserAgent->new();
$ua->proxy( http => $ENV{HTTP_PROXY});
print Dumper($ua);
my $request = new HTTP::Request('GET', $link);
print Dumper( $request );
and this is the dumper for UserAgent
$VAR1 = bless( {
'max_redirect' => 7,
'protocols_forbidden' => undef,
'show_progress' => undef,
'handlers' => {
'response_header' => bless( [
{
'owner' => 'LWP::UserAgent::parse_head',
'callback' => sub { "DUMMY" },
'm_media_type' => 'html',
'line' => 'C:/Perl/lib/LWP/UserAgent.pm:612'
}
], 'HTTP::Config' ),
'request_preprepare' => bless( [
{
'owner' => 'LWP::UserAgent::proxy',
'callback' => sub { "DUMMY" },
'line' => 'C:/Perl/lib/LWP/UserAgent.pm:920'
}
], 'HTTP::Config' )
},
'no_proxy' => [],
'protocols_allowed' => undef,
'local_address' => undef,
'use_eval' => 1,
'requests_redirectable' => [
'GET',
'HEAD'
],
'timeout' => 90,
'def_headers' => bless( {
'user-agent' => 'libwww-perl/5.837'
}, 'HTTP::Headers' ),
'proxy' => {
'http' => 'http://igate:8080'
},
'max_size' => undef
}, 'LWP::UserAgent' );
And this is for the request:
$VAR1 = bless( {
'_content' => '',
'_uri' => bless( do{\(my $o = 'https://some_link')}, 'URI::https' ),
'_headers' => bless( {}, 'HTTP::Headers' ),
'_method' => 'GET'
}, 'HTTP::Request' );
the problem is that the response is an error:
FAIL response, 500 proxy connect failed: PROXY ERROR HEADER, could be non-SSL URL:
HTTP/1.1 503 Service Unavailable
I'm using ActiveState perl 5.10.1 on a WinXP machine
when accessing the link from browser it work
Can somebody help?
Thanks
I've always needed to set https_proxy (rather than just http_proxy) to work with SSL URIs.

dereferencing data from multiple hash and array data structure in perl

Trying to extract data from detailed -> doc -> params -> parameters -> name in following DoxyDocs1.pm file; also including sample of script that extracts some data, but having trouble extracting params -> parameters -> name. Uncomment commented sections to see data.
#!/bin/perl
use Data::Dumper;
use warnings;
require "DoxyDocs1.pm";
print "API Content Analyzer\n";
&GenerateClassInfo($doxydocs->{classes});
sub GenerateClassInfo()
{
my ($classes) = #_;
foreach my $class (#$classes) {
print "\nClass name is: $class->{name}\n";
foreach my $pubmeth (#{$class->{public_methods}->{members}}) {
print "\n" if exists $pubmeth->{name};
print "\tpublic methods include: $pubmeth->{name}\n";
my ($key, $pmcontent) = each (#{$pubmeth->{detailed}->{doc}});
print "\t\tdescription: $pmcontent->{content}\n" if exists $pmcontent->{content};
# foreach my $pmp (#{$pubmeth->{detailed}->{doc}}) {
# print "\t\t";
# print Dumper($pmp);
# }
print "\t\tkind: $pubmeth->{kind}\n";
print "\t\ttype: $pubmeth->{type}\n" if exists $pubmeth->{type};
}
foreach my $privmeth (#{$class->{private_methods}->{members}}) {
print "\n" if exists $privmeth->{name};
print "\tprivate methods include: $privmeth->{name}\n";
my ($key, $pmcontent) = each (#{$privmeth->{detailed}->{doc}});
print "\t\tdescription: $pmcontent->{content}\n" if exists $pmcontent->{content};
# foreach my $info (#{$privmeth->{detailed}->{doc}}) {
# print "\t\t";
# print Dumper($info);
# }
print "\t\tkind: $privmeth->{kind}\n";
print "\t\ttype: $privmeth->{type}\n" if exists $privmeth->{type};
}
}
}
Example DoxyDocs1.pm file
$doxydocs=
{
classes => [
{
name => 'Panoply::Composite',
public_methods => {
members => [
{
kind => 'function',
name => 'addChild',
virtualness => 'non_virtual',
protection => 'public',
static => 'no',
brief => {},
detailed => {
doc => [
{
type => 'text',
content => 'Add a child to the container '
},
params => [
{
parameters => [
{
name => 'child'
}
],
doc => [
{
type => 'text',
content => 'is the child element to add'
}
]
}
]
]
},
type => 'void',
const => 'no',
volatile => 'no',
parameters => [
{
declaration_name => 'child',
type => 'Ptr'
}
]
},
{
kind => 'function',
name => 'operator<',
virtualness => 'non_virtual',
protection => 'public',
static => 'no',
brief => {},
detailed => {
doc => [
{
type => 'text',
content => 'Less than operator'
},
{
type => 'parbreak'
},
params => [
{
parameters => [
{
name => 'rval'
}
],
doc => [
{
type => 'text',
content => 'The '
},
{
type => 'url',
link => 'classPanoply_1_1Package',
content => 'Package'
},
{
type => 'text',
content => ' against which we are comparing this one. '
}
]
}
],
{
return => [
{
type => 'text',
content => 'true if this.packageID < rval.packageID, false otherwise.'
}
]
}
]
},
type => 'bool',
const => 'yes',
volatile => 'no',
parameters => [
{
declaration_name => 'rval',
type => 'const Composite &'
}
]
},
]
},
private_methods => {
members => [
{
kind => 'function',
name => 'addChild',
virtualness => 'virtual',
protection => 'private',
static => 'no',
brief => {},
detailed => {
doc => [
{
type => 'text',
content => 'Add a child to the container '
},
params => [
{
parameters => [
{
name => 'child'
}
],
doc => [
{
type => 'text',
content => 'is the child element to add '
}
]
},
{
parameters => [
{
name => 'parent'
}
],
doc => [
{
type => 'parbreak'
},
{
type => 'text',
content => 'is this own parent, except in weak pointer format to avoid a memory leak'
}
]
}
]
]
},
type => 'virtual void',
const => 'no',
volatile => 'no',
parameters => [
{
declaration_name => 'child',
type => 'Ptr'
},
{
declaration_name => 'parent',
type => 'Ptr'
}
]
},
]
},
}
]
};
1;
You said you wanted
detailed -> doc -> params -> parameters -> name
but that's missing many indexes. Which doc, param and parameters do you want?
detailed -> doc -> ??? -> params -> ??? -> parameters -> ??? -> name
The syntax is:
$member->{detailed}->{doc}->[$i]->{params}->[$j]->{parameters}->[$k]->{name}
Or for short:
$member->{detailed}{doc}[$i]{params}[$j]{parameters}[$k]{name}
If you want to loop over every doc, params, parameter, you can use:
my $docs = $member->{detailed}{doc};
for my $doc (#$docs) {
my $params = $doc->{params};
for my $param (#$params) {
my $parameters = $param->{parameters};
for my $parameter (#$parameters) {
...
}
}
}
(Why is doc singular and params and parameters plural??? Why do params have parameters???)

Can this be done with LDAP functions?

I have this code which works.
#!/usr/bin/perl
use warnings;
use strict;
use Net::LDAP;
use Data::Dumper;
my $dn="...";
my $password="...";
my $ldap = Net::LDAP->new('...') or die "$#";
my $mesg = $ldap->bind($dn, password => $password);
if ($mesg->code) { die "uuuu $mesg"; }
$mesg = $ldap->search(
base => "...",
scope => 'one',
filter => '(groupType=-2147483646)',
attrs => ['sAMAccountName'],
);
my #ad = ( );
foreach ($mesg->entries) {
push #ad, $_->asn->{attributes}[0]->{vals}[0];
}
foreach (#ad) {
print;
print "\n";
}
and outputs the name of the security groups.
So I was wondering, if LDAP (Active Directory) have functions to extract the values from the tree rather than having to do hardcode the path using arrays and hashes like I do in
push #ad, $_->asn->{attributes}[0]->{vals}[0];
The tree looks like this
'entries' => [
bless( {
'changes' => [],
'changetype' => 'modify',
'asn' => {
'objectName' => '...',
'attributes' => [
{
'type' => 'sAMAccountName',
'vals' => [
'test-group-1'
]
}
]
}
}, 'Net::LDAP::Entry' ),
bless( {
'changes' => [],
'changetype' => 'modify',
'asn' => {
'objectName' => '...',
'attributes' => [
{
'type' => 'sAMAccountName',
'vals' => [
'test-group-3'
]
}
]
}
}, 'Net::LDAP::Entry' )
],
push #ad, $_->get_value('sAMAccountName');