Displaying content of a hash {Perl} [duplicate] - perl

This question already has answers here:
What's the difference between a hash and hash reference in Perl?
(4 answers)
Closed 5 years ago.
I'm currently working with an API, and I wrote a short script to get details of a project I created. I'm able tu successfuly display the whole content with Data::Dumper but I cannot display a specific element or assign it to a variable.
Here is my short code :
# !/usr/bin/perl
use strict;
use warnings;
use TestLink::API;
use Data::Dumper;
my $tl=TestLink::API->new('http://127.0.0.1/testlink-1.9.16/lib/api/xmlrpc/v1/xmlrpc.php', 'a64aaa61db4e9f65d4e52745b86e3d8f');
print Dumper($tl->getProjectByName('Created_With_API'));
my %hachage = $tl->getProjectByName('Created_With_API');
And this code display my information, ie :
$VAR1 = {
'prefix' => 'CWAPI',
'notes' => 'res ipsa loquiter',
'opt' => {
'inventoryEnabled' => '1',
'testPriorityEnabled' => '1',
'automationEnabled' => '1',
'requirementsEnabled' => '1'
},
'options' => 'O:8:"stdClass":4:{s:19:"requirementsEnabled";i:1;s:19:"testPriorityEnabled";i:1;s:17:"automationEnabled";i:1;s:16:"inventoryEnabled";i:1;}',
'color' => '',
'option_priority' => '0',
'issue_tracker_enabled' => '0',
'id' => '14',
'is_public' => '1',
'option_reqs' => '0',
'type' => 'project',
'api_key' => '9bc99494a418140a1a625257da91d9f855b452c05f498ac2db94cbbbb331db58',
'name' => 'Created_With_API',
'option_automation' => '0',
'reqmgr_integration_enabled' => '0',
'tc_counter' => '0',
'active' => '1'
};
But I can't display a specific element, when I write
print "$hachage{id}";
I get an error. I KNOW, I'm probably doing something wrong, I started learning Perl a few days ago for this API and there must be awfull things. But I'd just like to know what am I doing wrong.
Thanks for your help for those who will take time to answer me ;)

getProjectByName doesn't return a list of key/value pairs (which is what you would need to initialize a %hash), it returns a single value, which is a reference to a hash:
my $hachage = $tl->getProjectByName('Created_With_API');
You can access single elements using e.g. $hachage->{id}. See perldoc perlreftut for more information.

You will need to create initialise your variable like this
my $hachage = $tl->getProjectByName('Created_With_API');
(Note dollar sign, not percent)
and you can get what you want by doing print "$hachage->{'id'}"
You need this syntax because $tl->getProjectByName returns a reference to a hash, not an actual hash.
The difference is discussed here.

Related

Get Values out of Complex Perl Hash Structures

With the following Code I can fetch Data stored in a Hash from a Database and print it out:
use Data::Dumper;
my $fdx = $s->field(); # get Hashreference from Database
print Dumper($fdx); # print out Hash
The (important part of the) Output looks like this:
$VAR1 = bless( {
'selectable' => 'true',
'_PARENT_OBJECT' => bless( {
'dirtyFlag' => 1,
'path' => undef,
'testItems' => [],
'data' => {
'TEST_10' => {
'atm_rundatahistory' => {
'1523964918' => {
'atm_prid' => {
'content' => '',
'label' => 'Problem Report IDs',
'raw' => ''
}, ...
'1523964410' => {
'atm_prid' => {
'label' => 'Problem Report IDs',
'raw' => '23361234',
'content' => '23361234'
}, ...
'Test_10' is one of hundreds of Tests, '1523964918' is one of many unix timestamps, so basically its a 32 Bit Integer, but I dont know which numbers the timestamps contain.
How do I print out / access the values for 'content' (in this case '23361234') of the most inner Hashes, for all Tests and unix timestamps, if they exist?
from here on I will describe my thoughts and what I have tried, its not necessary to read any further for this question.
I think the code I am looking for is something like:
foreach my $val($fdx{_PARENT_OBJECT}{data}{"TEST_*"}{atm_rundatahistory}{"********"}{atm_prid}{content})
print("\n$val");
However I don't know the exact Syntax, and neither do I know which placeholders to set for "Test_10", since there are many tests numbers, e.g. "...Test_132...Test_134" and the Unix timestamps can be any 32 Bit Integer, so I guess I can use start as a placeholder? e.g. "********".
After some hours of searching on the web, I haven't found a understandable tutorial on how to access values from complex Perl hash structures, I guess there are some simple syntax-rules to know and you can get any value of even very complex data structures without to much effort.
I've already read perldoc_perlreftut. If there is any other easy to understandable tutorial for these kind of problems, please recommend them to me. I don't really know how I can learn to handle such complex data structures in Perl myself.

eBay API - GerOrders not giving any results

I'm trying to figure out why my GetOrders function for the eBay API isn't working. Below are the headers I'm passing (this is in Perl):
$objHeader->push_header('X-EBAY-API-COMPATIBILITY-LEVEL' => $compatabilityLevel);
$objHeader->push_header('X-EBAY-API-DEV-NAME' => $devID);
$objHeader->push_header('X-EBAY-API-APP-NAME' => $appID);
$objHeader->push_header('X-EBAY-API-CERT-NAME' => $certID);
$objHeader->push_header('X-EBAY-API-CALL-NAME' => 'GetOrders');
$objHeader->push_header('X-EBAY-API-SITEID' => '3');
$objHeader->push_header('Content-Type' => 'text/xml');
...and the XML I'm passing is as follows:
<?xml version="1.0" encoding="utf-8" ?>
<GetOrdersRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<DetailLevel>ReturnAll</DetailLevel>
<NumberOfDays>3</NumberOfDays>
<OrderRole>Seller</OrderRole><OrderStatus>Active</OrderStatus>
<RequesterCredentials><eBayAuthToken>$userToken</eBayAuthToken></RequesterCredentials>
</GetOrdersRequest>
(obviously $userToken is replaced with my actual user token)
I get a return from it:
$VAR1 = {
'xmlns' => 'urn:ebay:apis:eBLBaseComponents',
'Build' => 'E929_CORE_APIXO_17568878_R1',
'PageNumber' => '1',
'PaginationResult' => {
'TotalNumberOfPages' => '0',
'TotalNumberOfEntries' => '0'
},
'OrderArray' => {},
'Ack' => 'Success',
'HasMoreOrders' => 'false',
'Timestamp' => '2015-06-29T09:49:25.963Z',
'Version' => '929',
'ReturnedOrderCountActual' => '0',
'OrdersPerPage' => '100'
};
..but as you can see, no results. I know for a fact there are results (I've had it working with the PHP API already using the same kind of values as far as I can tell). Worst case scenario, I could create a basic PHP script to grab the results, and then pipe into the Perl script. Obviously this isn't ideal though (I would much prefer to have it all in one programming language)
Anyone got any ideas? I'm drawing a blank on it :/
Ok, I knew this would happen. 2 days of battling with this, and then as soon as I post something - I find the solution :)
The issue was that I was passing the following in the XML:
<OrderStatus>Active</OrderStatus>
It in fact needed to be:
<OrderStatus>Completed</OrderStatus>
That is now grabbing them perfectly :)

perl hash ref operator is working weirdly

I m having a single array ref consisting a list of hash refs.
Here is the code:
use strict;
use warnings;
my $arrayRef = [
{
'URL' => 'http://example.com/1.jpg',
'ORD' => '1',
},
{
'URL' => 'http://example.com/2.jpg',
'ORD' => '2',
},
{
'URL' => 'http://example.com/3.jpg',
'ORD' => '3',
},
];
print $arrayRef->[0]->{URL},"\n"; # http://example.com/1.jpg
print $arrayRef->[0]{URL},"\n"; # http://example.com/1.jpg
Since it is an hash ref i am using -> operator to get a value, but i m getting the same value without using the -> operator is it fine?
It's valid, a kind of syntactic sugar, and it refers to the same item. The Perl references tutorial writes about this

How can I look and search for a key inside a heavily nested hash?

I am trying to check if a BIG hash has any keys from small hash and see if they exist, and if they do modify the BigHash with updated values from small hash.
So the lookup hash would look like this :
configure =(
CommonParameter => {
'SibSendOverride' => 'true',
'SibOverrideEnabledFlag' => 'true',
'SiPosition' => '8',
'Period' => '11'
}
)
But the BigHash is very very nested.. The key/hash CommonParameter from the small hash configure is there in the BigHash.
Can somebody help/suggest some ideas for me please?
Here is an example BigHash :
%BigHash = (
'SibConfig' => {
'CELL' => {
'Sib9' => {
'HnbName' => 'HnbName',
'CommonParameter' => {
'SibSendOverride' => 'false',
'SibMaskOverrideEnabledFlag' => 'false',
'SiPosition' => '0',
'Period' => '8'
}
}
}
},
)
I hope I was clear in my question. Trying to modify values of heavily nested BigHash based on Lookup Hash if those keys exist.
Can somebody help me? I am not approaching this in the right way. Is there a neat little key lookup fucntion or something available perhaps?
Give Data::Search a try.
use Data::Search;
#results = Data::Search::datasearch(
data => $BigHash, search => 'keys',
find => 'CommonParameter',
return => 'hashcontainer');
foreach $result (#results) {
# result is a hashref that has 'CommonParameter' as a key
if ($result->{CommonParameter}{AnotherKey} ne $AnotherValue) {
print STDERR "AnotherKey was ", $result->{CommonParameter}{AnotherKey},
" ... fixing\n";
$result->{CommonParameter}{AnotherKey} = $AnotherValue;
}
}

wordpress WP Query and Custom Field filtering

I've encoutered problem with filtering pages to display in WP query.
I use Codex WP query reference for custom fields with ACF (Advanced Custom Fields plugin - but it doesn't matter, couse it works same as WP custom field) parameters to filter pages.
In "Multiple Custom Field Handling" paragraph, Codex got an example with 2 conditions. We can use OR or AND relation. I works for both until you have 3rd condition (array).
They use example:
'relation' => 'OR',
array(
'key' => 'color',
'value' => 'blue',
'compare' => 'NOT LIKE'
),
array(
'key' => 'price',
'value' => array( 20, 100 ),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
It has only 2 arrays. When I put 3rd, nothing shows. In debug mode I can see an error:
WordPress database error: [Lost connection to MySQL server during query]
When I use AND it works, but I got to use OR. Unfortunately it makes MySQL disconnect.
I've tryed asking phpMySQL for same query WP does. It couses problem - phpMyAdmin says same:
Lost connection
Any Idea?
Maybe I should try different aproach for filtering? (maybe I should use taxonomy?)
Here is code I use:
$query_array = array('relation' => 'OR');
array_push($query_array,
array(
'key' => 'filter1',
'value' => 'value1',
'compare' => 'LIKE'
),
array(
'key' => 'filter1',
'value' => 'value2',
'compare' => 'LIKE'
),
array(
'key' => 'filter1',
'value' => 'value3',
'compare' => 'LIKE'
)
);
$args = array(
'order' => $order_array,
'meta_key' => $meta_key,
'orderby' => $orderby,
'post_type' => 'page',
'paged' => $paged,
'post__in' => $postIDs,
'posts_per_page' => 12,
'paged' => get_query_var('paged'),
'meta_query' => $query_array
);
query_posts($args);
?>
(variables for $args are set of course)
I don't know why I can't use
'compare' => '='
but probably it is why I can't use:
$query_array = array('relation' => 'OR');
array_push($query_array,
array(
'key' => 'filter1',
'value' => array('value1', 'value2', 'value3'),
'compare' => 'IN'
)
);
Just wanted to say that your comment helped me; I'd been butting my head against a very similar problem for a while. I'm using ACF too, and using it to attach items of one post type to another custom post type was easy - for instance, to Attach Person_1 and Person_3 to "Project_A".
This made it easy to list out which users were attached to specific projects. But when it came to do the same in reverse - to show which projects were attached to which users - it became a massive headache.
I finally figured it out, in part thanks to your comment - I'll post my solution here in case someone else comes along with the same problem:
$args = array(
'numberposts' => -1,
'post_type' => 'project',
'meta_query' => array(
'relation' => 'IN',
array(
'key' => 'people',
'value' => ';s:1:"' . $person->ID . '";',
'compare' => 'LIKE'
)
)
);
In short: because the ACF values in repeater fields et cetera are serialized, the compare keyword has to be "LIKE", and I added some context to the value to eliminate false returns - just searching for an ID like "1" would match a lot of the (wrong) posts, but the ";s1;" part ensures that the given value is at index 1, which in my case is the correct index.
So it would need tweaking from case to case. Inspecting what you're trying to match up with var_dumping "get_post_meta($post->ID, 'people')" is helpful for getting the value correct.