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

I am trying to understand this object and reference part of perl. The $p is an object here and &cb is a reference but I cant understand how this all works here. Can someone please explain this???
use HTML::LinkExtor; $p = HTML::LinkExtor->new(\&cb, "http://www.perl.com";); sub cb { my($tag, %links) = @_; print FIL "$tag @{[%links]}\n"; } $p->parse_file("index.html");

Replies are listed 'Best First'.
(jeffa) Re: Cant figure out this part?
by jeffa (Bishop) on Aug 06, 2002 at 14:25 UTC
    Just some further explanation for you. 'cb' stands for 'callback' - pass subroutine foo subroutine bar and call foo within bar. Here is a silly example to meditate on:
    use strict; sub decorate { my ($cb,$text) = @_; return $cb->($text); } my %sub = ( bold => sub { return '<b>' . shift() . '</b>' }, ital => sub { return '<i>' . shift() . '</i>' }, undl => sub { return '<u>' . shift() . '</u>' }, ); for (keys %sub) { print decorate($sub{$_},'foobar'), "\n"; }
    Here is a decent explanation of callbacks, the tutorial is really about Gtk. Callbacks are used extensively in GUI programming. The idea is to assign a subroutine to a widget such as a button. When the user clicks that button, the button calls the subroutine that was assigned to it. This allows the GUI programmer to easily add functionality.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Cant figure out this part?
by dreadpiratepeter (Priest) on Aug 06, 2002 at 13:53 UTC
    Actually, $p is a scalar that contains a reference to an object, but we can easily maintain the illusion that $p is the object.
    &cb is a function, not a reference. \&cb is a reference to the function.
    So what you have is a function, HTML::LinkExtor::new, being called as a method (using the -> syntax) that takes a reference to a function and a string as parameters, and returns an object. It's being used as a constructor.
    Careful reading of chapters 8-12 of the Camel book will offer enlightenment.

    -pete
    "Pain heals. Chicks dig scars. Glory lasts forever."
Re: Cant figure out this part?
by derby (Abbot) on Aug 06, 2002 at 14:44 UTC
    ++ the comments above. Just to add though, $cb is a "callback." Callbacks are great mechanisms for adding your "specialized" code into a generic framework. In this particular case, your cb subroutine will be called as links are found during the parsing of the "index.html". You see quite a bit of use of the callback approach in parsing style modules (XML, HTML, etc), gui modules (Tk, Gtk, etc), dispatch tables, and signal handlers. Page 53 of Advanced Perl Programming has a pretty good definition of callbacks:

    A callback function is an ordinary subroutine whose reference is passed around. The caller (who uses that function) doesn't neccessarily have an idea of which subroutine is getting invoked.

    -derby

    update: darn that jeffa. I think perlmonks needs an "oops I'm too slow" button.

Re: Cant figure out this part?
by ides (Deacon) on Aug 06, 2002 at 13:55 UTC

    What is happening here is that you are passing in a reference to the subroutine 'cb' into the object $p which is a HTML::LinkExtor object.

    By doing this $p can use the subroutine you provide so that you can customize the work being done on the extracted links. You seem to be printing them to a file, but lets say for example you wanted to build a spider, you could then write a sub spider { ... } that would traverse the links you find recursively. You would then create it with something like this:

    use HTML::LinkExtor; my $p = HTML::LinkExtor->new(\&spider, "http://www.perl.com"); sub spider { # code omited } $p->parse_file("index.html");

    Hope this helps.

    -----------------------------------
    Frank Wiles <frank@wiles.org>
    http://frank.wiles.org