in reply to SDLx handlers and Moose

You have to pass the parameters from the callback to your method, something like:

$app->add_move_handler ( sub { $ship->move( @_ ) } ); $app->add_show_handler ( sub { $ship->draw( @_ ) } );

Improve your skills with Modern Perl: the free book.

Replies are listed 'Best First'.
Re^2: SDLx handlers and Moose
by Ransom (Beadle) on May 25, 2012 at 12:18 UTC

    Alright so that works like a charm. My new question is why must I use the sub keyword when adding the methods as callbacks? Shouldn't it already be obvious I'm calling a method in a class? I'm assuming I'm missing some knowledge about perl oop but I've read just about everything I can get my hands on.

    Anyway thank you for your quick help and accurate response (I admit I was pretty darn skeptical).

    Ransom
      My new question is why must I use the sub keyword when adding the methods as callbacks?

      How else is Perl to know that you mean to pass a function reference? Remember that curly braces in Perl 5 can mean any of three things: a hash reference, a block, or an anonymous function passed to a prototyped function.

      In effect, the code I posted:

      $app->add_move_handler ( sub { $ship->move( @_ ) } ); $app->add_show_handler ( sub { $ship->draw( @_ ) } );

      ... is a shorter version of this code, using anonymous functions instead:

      sub move_ship { $ship->draw( @_ ); } sub draw_ship { $ship->draw( @_ ); } $app->add_move_handler( \&move_ship ); $app->add_show_handler( \&draw_ship );

      ... or even:

      my $move_ship = sub { $ship->move( @_ ) }; my $draw_ship = sub { $ship->draw( @_ ) }; $app->add_move_handler( $move_ship ); $app->add_show_handler( $draw_ship );

      Do you follow so far?

      A callback is a reference to a function. If you put a method call where a callback is needed, it won't work as expected.

      # The first one is wrong. It adds a reference to an subroutine named f +or the return value of $ship->move (or \&1) # because print returns 1 when it is successful. $app->add_move_handler ( \&{$ship->move} ); $app->add_move_handler ( sub { $ship->move( @_ ) } );

      Try this to verify that:

      #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; $Data::Dumper::Deparse = 1; use Mob; my $ship = Mob->new(); my $first = \&{$ship->move}; print "first: ", Dumper( $first ); my $second = sub { $ship->move( @_ ) }; print "second: ", Dumper( $second ); # &$first(); # Uncomment to see the error 'Undefined subroutine &main: +:1 called at ./test.pl line 17.' &$second( 1, 2 );

      Update: chromatic replied while I was typing this up with more thorough answers than mine.

      My new question is why must I use the sub keyword when adding the methods as callbacks?

      Because of everything :) see Tutorials: Closure on Closures or read about it in chromatic's free book

        Because of... everything? Awesome, I'll just read the two tutorials about lexical scoping and clusures and... wait? What? No idea what I'm supposed to be learning here.

        In the hopes to have learned something from reading, the methods I created are outside of the closures of my main file?

        I'm having trouble relating how these tutorials affect A. My having to use the sub keyword... it IS a sub already and B. Why I must pass @_ to the sub when it was implicit before in this example:

        $app->add_event_handler( \&quit_event ); $app->add_move_handler ( \&calculate_laser ); $app->add_show_handler ( \&render_laser ); sub quit_event { my $event = shift; my $controller = shift; $controller->stop if $event->type == SDL_QUIT; } sub calculate_laser { # The step is the difference in Time calculated for the next jump my ( $step, $app, $t ) = @_; $laser += $velocity * $step; $phaser += $velocity * $step; $velocity = -$velocity if $laser > $app->w; $velocity = -$velocity if $laser < -20; } sub render_laser { my ($delta, $app) = @_; #draw bg $app->draw_rect( [0, 0, $app->w, $app->h ], 0); $app->draw_rect([$phaser, $app->h/4, 20, 4], [100, 100, 255, 255]) +; $app->draw_rect( [ $laser, $app->h / 2, 20, 4 ], [255, 8, 8, 255] +); $app->update(); }

        I'm fully aware that I may just be missing some major points on closures and lexical scoping, but after reading I'm just more confused as to what's going on rather than anything becoming clearer

        Ransom