Please Explain the Following Anonymous Sub

P

Picker Leon

##code with problems
#!/usr/bin/perl -w
use warnings;
use diagnostics;
use HTML::LinkExtor;

$input='<a href=hreflink></a> <img src=imglink>';

getlink ('img');
getlink ('a');

sub getlink{
my $matchkey = $_[0];
print "matchkey outsite callback $matchkey \n";

sub callback {
print "matchkey inside callback $matchkey\n";
return; #WHAT IS THE RETURN HERE FOR?
}

my $p = HTML::LinkExtor->new(\&callback);
$p->parse($input);
}
**************
output:
matchkey outsite callback img
matchkey inside callback img
matchkey inside callback img
matchkey outsite callback a
matchkey inside callback img
matchkey inside callback img
**************
I was told to change lines to those:
my $callback = sub { print "matchkey in $matchkey\n"; }; #WHY NO MORE
RETURN?
my $p = HTML::LinkExtor->new($callback);
*************
Here is the explain from perl:
(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.
************
What I don't understand is when I delete my, then it works perfectly. I
copied the code from linkextor, but apparently it only works if I use globle
varible not my varibles. I think linkextor should change their sample codes.
Please update it, Larry.
MY QUESTION IS WHY INNER AND OUTTER ARE NOT SHAREING THE MY VARIBLE? I THINK
LARRY SHOULD CHANGE THE BEHAVOUR OF MY TOO.
 
K

Keith Keller

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2003-12-06 said:
What I don't understand is when I delete my, then it works perfectly.

Which my? You have two in your original code, and the new line of code
suggested to you also has a my. If you want help, perhaps you should be
more specific.
I copied the code from linkextor, but apparently it only works if I use globle
varible not my varibles. I think linkextor should change their sample codes.
Please update it, Larry.

Did you even read perldoc HTML::LinkExtor? I think you'll find that
Larry doesn't maintain that module.

How do you suggest HTML::LinkExtor change its behaviour? You don't
appear to have found any sort of a bug, except in your own code.
MY QUESTION IS WHY INNER AND OUTTER ARE NOT SHAREING THE MY VARIBLE? I THINK
LARRY SHOULD CHANGE THE BEHAVOUR OF MY TOO.

IF YOU THINK IT'S THAT EASY TO CHANGE PERL'S BEHAVIOUR YOU SHOULD DO IT
YOURSELF.

And please stop shouting.

I haven't looked at the code for this particular quirk, but it is
probably sufficiently hairy that simply changing this particular
behaviour, and nothing else, is very much nontrivial. A few posts ago
you didn't even understand the differences between my, our, and local,
and now you're suggesting changes in my?

Finally, I'm sure that many of the more knowledgeable folks have either
already killfiled you or are considering doing so. If you wish to
continue to receive help, I'd suggest you think more carefully when you
compose your posts, to make sure you've done sufficient research into
your problem and that you're being sufficiently clear in what you think
is wrong.

- --keith

- --
(e-mail address removed)-francisco.ca.us
(try just my userid to email me)
AOLSFAQ=http://wombat.san-francisco.ca.us/cgi-bin/fom

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/0jW4hVcNCxZ5ID8RAh/4AJ4ydyb4UM+OFrQ3cuh7qJ8UUG26bgCgicO0
aFKcQI3Zygq/lRv84fhrwmg=
=mfZR
-----END PGP SIGNATURE-----
 
J

Jay Tilton

: ##code with problems
: #!/usr/bin/perl -w
: use warnings;
: use diagnostics;
: use HTML::LinkExtor;
:
: $input='<a href=hreflink></a> <img src=imglink>';
:
: getlink ('img');
: getlink ('a');
:
: sub getlink{
: my $matchkey = $_[0];
: print "matchkey outsite callback $matchkey \n";
:
: sub callback {
: print "matchkey inside callback $matchkey\n";
: return; #WHAT IS THE RETURN HERE FOR?
: }
:
: my $p = HTML::LinkExtor->new(\&callback);
: $p->parse($input);
: }
: **************
: output:
: matchkey outsite callback img
: matchkey inside callback img
: matchkey inside callback img
: matchkey outsite callback a
: matchkey inside callback img
: matchkey inside callback img
: **************
: I was told to change lines to those:
: my $callback = sub { print "matchkey in $matchkey\n"; }; #WHY NO MORE
: RETURN?

You're focusing on a trivial and irrelevant difference there.

With or without return(), control flow goes back to the calling statement.
If it's really bothering you, perldoc -f return explains what happens
differently with an explicit return() and without one.

: my $p = HTML::LinkExtor->new($callback);
: *************
: Here is the explain from perl:
: (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.
: ************
: What I don't understand is when I delete my, then it works perfectly.

There's not much to add to the diagnostics output.

Subroutine getlink() assigns a value to $matchkey.
The nested subroutine callback() will see that value of $matchkey, and it
will never recognize when getlink() changes it.

Don't nest named subroutines. It's that simple.

: I copied the code from linkextor,

I see no code in the HTML::LinkExtor documentation remotely resembling what
you have written above. What version of HTML::LinkExtor are you looking
at? Is there a URL available for us to see *exactly* where you got that
code?

: but apparently it only works if I use globle varible not my varibles.

That's true for the way you have it written, with the nested subroutine.

my() variables will work splendidly if you un-nest the callback()
subroutine and declare $matchkey in a scope enclosing both getlink() and
callback().

{ # bare block to limit the scope of $matchkey
my $matchkey;

sub getlink{
$matchkey = $_[0];
print "matchkey outsite callback $matchkey \n";
my $p = HTML::LinkExtor->new(\&callback);
$p->parse($input);
}

sub callback {
print "matchkey inside callback $matchkey\n";
}
}

: I think linkextor should change their sample codes. Please update it,
: Larry.

Are you sure you're looking at a current version of the HTML::LinkExtor
documentation?

Larry is not the author of HTML::LinkExtor. The module's documentation
itself attributes copyright to Gisle Aas.

: MY QUESTION IS WHY INNER AND OUTTER ARE NOT SHAREING THE MY VARIBLE?

Please stop shouting.

: I THINK LARRY SHOULD CHANGE THE BEHAVOUR OF MY TOO.

Just because you can't get a grip on the documented behavior of how a
nested subroutine handles a lexical variable defined in the enclosing
subroutine? Fat chance.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top