in reply to Re: SDLx handlers and Moose
in thread SDLx handlers and Moose

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

Replies are listed 'Best First'.
Re^3: SDLx handlers and Moose
by chromatic (Archbishop) on May 25, 2012 at 17:08 UTC
    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?

Re^3: SDLx handlers and Moose
by Mr. Muskrat (Canon) on May 25, 2012 at 17:53 UTC

    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.

Re^3: SDLx handlers and Moose
by Anonymous Monk on May 25, 2012 at 13:18 UTC

    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
        Why I must pass @_ to the sub when it was implicit before in this example:

        The callbacks are function references. They're not methods; they have no invocants. SDL will invoke those references and pass the parameters it wants to them. SDL doesn't know you're using methods. SDL doesn't know which objects you want to use.

        Because you want to call methods on objects, you have to give SDL callbacks which are closures which then invoke methods on your objects.

        Because you're using that layer of indirection, you have to pass the arguments to your methods directly.