Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

comment on

( [id://3333] : superdoc . print w/replies, xml ) Need Help??

Callbacks are a way of getting some user supplied code run in a provider context. The "user" is your code. The "provider" is some fancy pants module or sub written by someone else (or by you being clever). I'm sure you are happy to pass parameters into a sub so the sub can do some work with them. Well, a callback is just some code (a reference to a sub) that you pass as a parameter so the called sub can do some work with it.

Why would you want to do that? In the example you give (I'm guessing) you are providing a sub that will get called to handle web page that has been fetched. In other cases you might provide a callback to do some math on data points as part of an algorithm that searches for patterns in a data set. The search algorithm remains the same for different match conditions - you are passing in the bit that is tuned for a specific type of match.

So the parameter you are passing is just a reference to a sub (that's the \& bit). That can be provided in a bunch of different ways and may often use closures to pass some of your calling context into the callback - that is deep magic indeed! Let's take a look:

use strict; use warnings; my $helloWorld = sub{return "Hello world 1"}; process($helloWorld); process(sub{return "Hello world 2"}); process(\&helloWorld); process(sub{return $_}) for 1 .. 5; process(sub{mul10($_)}) for 1 .. 5; sub helloWorld { return "Hello World 3"; } sub mul10 { my ($x) = @_; return $x * 10; } sub process { my ($callback) = @_; print $callback->(), "\n"; }


Hello world 1 Hello world 2 Hello World 3 1 2 3 4 5 10 20 30 40 50

The process calls with (sub...) are all creating a sub on the fly. sub returns a reference to the subroutine. You can see that with $helloWorld. The \& variant calls a sub defined somewhere else. The last two with the for loop modifiers use closures to pass the default variable into the called subroutine. Closures are subtle and can do astounding things - in fact quite often what they do is astounding in a disconcerting way!

As a matter of course I use a line of the form my ($p1, $p2, $p3, ...) = @_; to provide local variables containing the values of passed in parameters. @_ is the list of aliases to the parameters passed to the sub.  my (...) declares a list of variables that get assigned values from the @_ parameter list. You can use undef as a place holder for a parameter that you aren't interested in - i.e.: to ignore the parameter.

Premature optimization is the root of all job security

In reply to Re: Trying to Understand Callback(s) by GrandFather
in thread Trying to Understand Callback(s) by DanielSpaniel

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.