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

Hi All
I've created the following script:
use strict; use warnings; use LWP::Simple; # from CPAN use JSON qw( decode_json ); # from CPAN #get my address use LWP::UserAgent; my $ua = LWP::UserAgent->new; my $server_endpoint = "https://www.googleapis.com/geolocation/v1/geolo +cate?key=MY API KEY"; # set custom HTTP request header fields my $req = new HTTP::Request POST =>( $server_endpoint); $req->header('content-type' => 'application/json'); # add POST data to HTTP request body my $post_data = '{"homeMobileCountryCode" : 235, "homeMobileNetworkCode" : 77, "radioType" : "gsm", "carrier" : "BT Group", "considerIp" : "true"}'; $req->content($post_data); my $resp = $ua->request($req); my $message = $resp->decoded_content; print "Received Reply:$message\n";
Which successfully prints
Received Reply:{ "location": { "lat": 53.4232611, "lng": -1.0836272999999998 }, "accuracy": 901.0 }
What I need to do now is get the lat and lng values to use in a new script, but I just cant do it. I'm trying
my $lat = $message->{"location"}{"lat"};
but I get the error message
Can't use string ("{ "location": { "lat": 53.423"...) as a HASH ref while "strict refs" in use at etc.e +tc.
Please point me in the right direction

Replies are listed 'Best First'.
Re: Using Google APIs for Lattitude
by huck (Prior) on Jul 03, 2017 at 20:14 UTC

    try adding this

    use JSON; my $json=new JSON; my $unjson; eval{ $unjson=$json->allow_nonref->decode($message);} ; warn 'json decode error:'.$@ ."\n" if ($@); my $lat = $unjson->{"location"}{"lat"};

      Nice huck, but I'd just like to give you a tidbit...

      $@ is an interesting variable. As soon as you go into an eval, you overwrite (clear) that var immediately. Worse, because of its nature, it could be set elsewhere even while you're in your eval call, rendering your use of it useless, or worse, confusing. For these reasons, base a warn or other activities on whether the eval caught a throw directly, not on $@ which could be set somewhere else, even far away, that's not related even remotely to your check:

      use JSON; my $json = new JSON; my $unjson; my $statement_ok = eval { $unjson = $json->allow_nonref->decode($message); 1; }; if (! $statement_ok){ # $@ can be interpolated ;) warn "json decode error: $@\n"; } my $lat = $unjson->{"location"}{"lat"};

      If eval catches an exception, the true (1;) will never be returned, rendering $statement_ok undef, allowing you act based on the result of the eval, not whether $@ is set or not. You could further it a bit (untested):

      my $ok = eval { foo(); 1; }; if (! $ok){ if ($@ =~ /internal error/){ warn "foo() fsck'd up!\n"; } else { warn "foo() fsck'd up, with unexpected err: $@\n"; } }

      Looking at Try::Tiny, it explains what I've said in detail. That module is a different approach to your excellent example.

      Huck

      Spot on worked like a treat, the main goal here is to use my pi to locate my phone, and if its a certain distance from home switch off my heating. I already have my heating controlled by the weather and if my solar panels are generating, this will enable me to reach the next step.

      Many Thanks

Re: Using Google APIs for Lattitude
by stevieb (Canon) on Jul 03, 2017 at 20:02 UTC

    Hi mattpower,

    Please edit your question and use <p></p> tags around your sentences, and <code></code> tags around your code, any input data, and any expected output data.