in reply to Why callbacks?

No need for globals, just have the coderef use lexicals in the scope it's declared in (i.e. use a closure).

{ my $returned_data = [ ]; sub my_fetch_callback { push @{ $returned_data }, $_[0] } routine_wanting_callback( \&my_fetch_callback ); for my $datum ( @{ $returned_data } ) { munge_it( $datum ); } }

Update: Moved bracket after for so it would, you know, actually work. Duurr. Stupid trees making pollen affecting sinuses with their pollen making brane numbing congestion stuff.

Another example: You could also pass a coderef which stores the results by calling methods on an object you provide.

my $line_holder = Line::Holding->new( ); routine_wanting_callback( sub { $line_holder->hold( $_[0] ) } ); $line_holder->process_held_lines;

Nothing says the callback has to call a named subroutine sitting in the symbol table (unless the callback wanting routine says it takes the name of a subroutine of course; but that'd just be bad design :).

Replies are listed 'Best First'.
Re^2: Why callbacks?
by pileofrogs (Priest) on Mar 30, 2007 at 17:19 UTC

    Woah... doesn't my_fetch_callback go out of scope before you can call it?

      Named subroutines never go out of scope; they're global - bound to a package just like global variables.

      Anonymous subrefs can go out of scope, just like any other variable, but, just like any other variable, you can pass them around:

      sub call { my ($arg1,$arg2) = @_; my $callback = sub { my ($arg3) = @_; return $arg1 + $arg2 + $arg3; }; call_func_needing_callback($callback); } # or even sub call { my ($arg1,$arg2) = @_; call_func_needing_callback( sub { my ($arg3) = @_; return $arg1 + $arg2 + $arg3; }); }

      Also note that there are scoping issues with defining named closures within other subroutines (this probably has to do with named subroutines being global), while unnamed subroutines/closures will work as real lexical closures.

      I presume this was asked before I moved the brace, but even then no. The scalar would have (which is why I made the correction), but the subroutine sticks around (they're not lexically declared). Had I done this:

      { my $returned_data = []; my $callback = sub { push @{ $returned_data }, $_[0] }; } something_wanting_callback( $callback );

      Then yes, that coderef would have gone out of scope.

        So, all subrutines are in effect global? Huh.. I didn't know that.

        -Pileofrogs

        In Other News:
        Whoever keeps downvoting me, please tell me what it is that you don't like... I can't get better if you don't tell me what's wrong...