1

There is a simple code to query storm api

#!/usr/bin/env perl
use strict;
use warnings;
use HTTP::Request;
use LWP::UserAgent;
use LWP::Simple;
use JSON::XS;
use Try::Tiny;
use Data::Dumper;

my $ua = LWP::UserAgent->new; 
my $status = $ua->get("http://lab7.local:8888/api/v1/topology/summary");
my $sts = $status->decoded_content;
my $coder = JSON::XS->new->ascii->pretty->allow_nonref;
my $out = try {my $output = $coder->decode($sts)} catch {undef};
print Dumper(\%$out);

The output

$VAR1 = {
      'topologies' => [
                        {
                          'encodedId' => 'subscriptions_lab_product-8-1452610838',
                          'workersTotal' => 1,
                          'status' => 'ACTIVE',
                          'uptime' => '35m 54s',
                          'name' => 'subscriptions_lab_product',
                          'id' => 'subscriptions_lab_product-8-1452610838',
                          'tasksTotal' => 342,
                          'executorsTotal' => 342
                        }
                      ]
    };

How can i get for example the 'id' value of inner hash?
OS: RHEL6.6
Perl: 5.10.1

2
  • 3
    See perldsc for info on creating and accessing a variety of complex data structures in Perl. Commented Jan 12, 2016 at 16:23
  • 1
    You mean like $out->{topologies}->[0]->{id}? Commented Jan 12, 2016 at 16:24

2 Answers 2

3

If there is only one topology, it's simply what @MattJacob already said in his comment.

$out->{topologies}->[0]->{id}

If there are more, you can iterate.

my @ids;
foreach my $topology ( @{ $out->{topologies} } ) {
  push @ids, $topology->{id};
}

Here is a visual explanation including free-hand circles.

enter image description here

First there is a hash reference that only has the single key topologies.

$out->{topologies};

Under that key, there is an array reference. The elements in that array reference are hash references, but there is only one. To get that first one, use the index 0.

$out->{topologies}->[0];

Now you've got that hash reference with all the properties of the topology inside. You can use the key id to get the string on the right hand side of the dump.

$out->{topologies}->[0]->{id};

Also see perlreftut.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for visualized explanation. Btw it doesn't work with say but works with print. Useless use of hash element in void context at ./storm_api.pl line 22. Can't call method "say" on unblessed reference at ./storm_api.pl line 22.
@user That's because you have to use feature 'say' to get that keyword. I replaced that with an array operation instead.
3

To answer your specific question, you need to use the dereference operator (->):

$out->{topologies}->[0]->{id}

Technically, the arrow is optional between subscripts, so the line above could be rewritten as:

$out->{topologies}[0]{id}

But since you're asking the question in the first place, I would recommend reading perldsc, perlref, and perlreftut to get a solid foundation for references in Perl.

2 Comments

I wasn't sure about 5.10, so I checked perldoc.perl.org/5.10.1/perlreftut.html#Arrow-Rule. The arrow is indeed already optional in that version. Didn't want to steal your answer btw. You were fast with your comment.
@simbabque Thanks, and no worries. I wrote the comment because I thought it was too simple for an answer, but then I realized that it does actually answer the question, so I expanded it into an answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.