Search code examples
perlmojoliciousmojo-useragent

"Use of uninitialized value $_" warning with a Mojo::UserAgent non-blocking request


I am trying to make a non-blocking request with Mojo::UserAgent but when I run the code below I get

Use of uninitialized value $_ in concatenation (.) or string

on the print line.

How can I access $_ inside the callback?

my $ua = Mojo::UserAgent->new();

my @ids = qw( id1  id2 id3 );

foreach ( @ids ) {

    my $res = $ua->get('http://my_site/rest/id/'.$_.'.json' => sub {
        my ($ua, $res) = @_;
        print "$_ => " . $res->result->json('/net/id/desc'), "\n";
    });
}

Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

Solution

  • $_ is a special kind of variable where the value depends on the context. Inside the foreach (@ip) context it is set as an alias of specific item in the @ip array. But, the callback for $ua->get(...) gets not executed within the foreach (@ip) context and thus $_ no longer is an alias into the @ip array.

    Instead of using this special variable you need to use a normal variable scoped inside the foreach (@ip) loop, so that it can be bound to the subroutine (see also What's a closure in perlfaq7):

    foreach (@ip) {
       my $THIS_IS_A_NORMAL_VARIABLE = $_;
       my $res= $ua->get( ...  => sub {
          my ($ua, $res) = @_;
          print  "$THIS_IS_A_NORMAL_VARIABLE =>" . $res->result->json('/net/id/desc'),"\n";
       });
    }