Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl6: NCurses and mouse events

I do not succeed in getting returned a mouse event from getmouse. Are there errors in my code?

#!/usr/bin/env perl6
use v6;
use NCurses;

my $win = initscr;
raw();
keypad( $win, True );
my Array[int32] $old;
mousemask( ALL_MOUSE_EVENTS +| REPORT_MOUSE_POSITION, $old ) or die;

loop {
    my $key = getch();
    if $key == KEY_MOUSE {
        my NCurses::MEVENT $event;
        my $ok = getmouse( $event );
        endwin;
        say "ok:    ", $ok.perl;    # -1
        say "event: ", $event.perl; # NCurses::MEVENT
        exit;
    }
}

NCurses

like image 905
sid_com Avatar asked Nov 30 '25 02:11

sid_com


1 Answers

The usual idiom

If you have to write a type's name as part of a variable declaration you might as well write it as the variable's type constraint and use .= new rather than using either Marty's or your solution:

my NCurses::MEVENT $event .= new

Marty's solution:

my $event = NCurses::MEVENT.new

works because $event now contains what the getevent($event) call needs it to contain, namely a new NCurses::MEVENT object. But it passes up an easy opportunity to add type-checking.

Your solution:

my NCurses::MEVENT $event = NCurses::MEVENT.new

means the same as the usual idiom for this situation but isn't DRY.

What went wrong

The line of code that glues the Perl 6 getmouse call to the underlying native NCurses library starts:

sub getmouse(MEVENT) ...

This tells Perl 6 that getmouse needs one argument of type NCurses::MEVENT.

Marty's solution worked. They didn't tell Perl 6 what type of value $event should contain. But they put the right value in it anyway so the lack of type-checking didn't matter.

Your original solution enabled useful type-checking. It told Perl 6 to make sure that $event only ever contained an object of type NCurses::MEVENT. Unfortunately you didn't explicitly initialize the variable so it contained...

Hang on. What did it contain? Shouldn't Perl 6 have made sure that there was an NCurses::MEVENT object in $event anyway?

In fact it did! But rather than putting an ordinary new NCurses::MEVENT object in there Perl 6 put an old NCurses::MEVENT type object in there as a placeholder. Among other things, Type objects represent the notion of an uninitialized object. (A bit like "undef" in Perl 5.)

This mechanism normally works well for surfacing errors like forgetting to suitably initialize a variable. But not in this case. So what went wrong?

Back to the getmouse declaration. It should have been:

sub getmouse(MEVENT:D) ...

The :D "type smiley" would tell Perl 6 that the argument has to be defined, ie that an uninitialized NCurses::MEVENT isn't good enough. With this smiley you'd have gotten an appropriate error rather than silence.

like image 126
raiph Avatar answered Dec 02 '25 17:12

raiph