Please Explain the Following Anonymous Sub

Discussion in 'Perl Misc' started by Picker Leon, Dec 6, 2003.

  1. Picker Leon

    Picker Leon Guest

    ##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.
     
    Picker Leon, Dec 6, 2003
    #1
    1. Advertising

  2. Picker Leon

    Keith Keller Guest

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

    On 2003-12-06, Picker Leon <> wrote:
    [snip]
    > 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

    - --
    -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-----
     
    Keith Keller, Dec 6, 2003
    #2
    1. Advertising

  3. Picker Leon

    Jay Tilton Guest

    "Picker Leon" <> wrote:

    : ##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.
     
    Jay Tilton, Dec 6, 2003
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. suzy
    Replies:
    3
    Views:
    450
  2. srikanth
    Replies:
    14
    Views:
    545
    vijay
    Jul 10, 2003
  3. Ben
    Replies:
    2
    Views:
    898
  4. Lawrence D'Oliveiro

    Death To Sub-Sub-Sub-Directories!

    Lawrence D'Oliveiro, May 5, 2011, in forum: Java
    Replies:
    92
    Views:
    2,041
    Lawrence D'Oliveiro
    May 20, 2011
  5. PerlPerl
    Replies:
    12
    Views:
    172
    A. Sinan Unur
    May 30, 2005
Loading...

Share This Page