use strict;
use warnings;
####
Variable "@imgs" will not stay shared at par.pl line 17 (#1)
####
C:\TEMP>perl -Mdiagnostics par.pl
perl -Mdiagnostics par.pl
Variable "@imgs" will not stay shared at par.pl line 17 (#1)
(W closure) An inner (nested) named subroutine is referencing a
lexical variable defined in an outer subroutine.
When the inner subroutine is called, it will probably see the value of
the outer subroutine's variable as it was before and during the *first*
call to the outer subroutine; in this case, after the first call to the
outer subroutine is complete, the inner and outer subroutines will no
longer share a common value for the variable. In other words, the
variable will no longer be shared.
Furthermore, if the outer subroutine is anonymous and references a
lexical variable outside itself, then the outer and inner subroutines
will never share the given variable.
This problem can usually be solved by making the inner subroutine
anonymous, using the sub {} syntax. When inner anonymous subs that
reference variables in outer subroutines are called or referenced, they
are automatically rebound to the current values of such variables.
####
use strict;
use warnings;
use HTML::LinkExtor;
use LWP::UserAgent;
use URI::URL;
sub parsedocument
{
my ($url) = @_;
my $ua = LWP::UserAgent->new;
$ua->env_proxy();
# Set up a callback that collect image links
my @imgs = ();
my $callback = sub {
my($tag, %attr) = @_;
return if $tag ne 'img'; # we only look closer at
push(@imgs, values %attr);
};
my $p = HTML::LinkExtor->new($callback);
# Request document and parse it as it arrives
my $res = $ua->request(HTTP::Request->new(GET => $url),
sub {$p->parse($_[0])});
# Expand all image URLs to absolute ones
my $base = $res->base;
@imgs = map { $_ = url($_, $base)->abs; } @imgs;
# Print them out
print join("
", @imgs), "
";
}
map {parsedocument($_) } @ARGV;