Perl6:NCurses 和鼠标事件
Perl6: NCurses and mouse events
我没有成功从 getmouse
返回鼠标事件。我的代码有错误吗?
#!/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;
}
}
我找到了缺失的部分:
#!/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 = NCurses::MEVENT.new;
my $ok = getmouse( $event );
endwin;
say "ok: ", $ok.perl;
say "event: ", $event.perl;
exit;
}
}
一个不太令人敬畏的静默失败掩盖了您正在将类型对象传递到 getmouse() 的事实。我只是通过在第 18 行将 $event.perl
替换为 $event.x
来找到它作为信息钓鱼探险。这样做会产生;
user@Ubuntu-iMac:~$ ./getmouse.p6
ok: -1
Invocant requires an instance of type NCurses::MEVENT, but a type object was passed. Did you forget a .new?
in block at ./getmouse.p6 line 17
...这只是提供了更多信息。
我相信你现在明白了,但是,为了记录,你输入了 $event 变量但没有给它赋值,所以它得到了根据 Perl6 class tutorial 的类型对象是一个未定义的 "empty instance" 类型。
通过简单地将第 13 行的 my NCurses::MEVENT $event;
替换为 my $event = NCurses::MEVENT.new;
,可以得到;
user@Ubuntu-iMac:~$ ./getmouse.p6
ok: 0
event: NCurses::MEVENT.new(id => 0, x => 70, y => 26, z => 0, bstate => 128)
...世界一切都好。
常用成语
如果您必须将类型名称写为变量声明的一部分,您不妨将其写为变量的类型约束并使用 .= new
而不是使用 Marty 或您的解决方案:
my NCurses::MEVENT $event .= new
马蒂的解决方案:
my $event = NCurses::MEVENT.new
起作用是因为 $event
现在包含 getevent($event)
调用需要它包含的内容,即一个新的 NCurses::MEVENT 对象。但是它放弃了一个简单的机会来添加类型检查。
您的解决方案:
my NCurses::MEVENT $event = NCurses::MEVENT.new
的意思与这种情况下的常用习语相同,但不是 DRY。
出了什么问题
line of code that glues the Perl 6 getmouse
call to the underlying native NCurses library开始:
sub getmouse(MEVENT) ...
这告诉 Perl 6 getmouse 需要一个 NCurses::MEVENT
.
类型的参数
马蒂的解决方案奏效了。他们没有告诉 Perl 6 $event
应该包含什么类型的值。但是他们无论如何都会在其中放入正确的值,因此缺少类型检查并不重要。
您的原始解决方案启用了有用的类型检查。它告诉 Perl 6 确保 $event
只包含一个 NCurses::MEVENT
类型的对象。不幸的是,您没有显式初始化变量,因此它包含...
等一下。它包含什么? Perl 6 不应该确保 $event
中有一个 NCurses::MEVENT
对象吗?
事实上它做到了!但是 Perl 6 并没有将 ordinary new NCurses::MEVENT
对象放入其中,而是将旧的 NCurses::MEVENT
type 对象放入其中一个占位符。除其他事项外,Type 对象表示未初始化对象的概念。 (有点像 Perl 5 中的“undef”。)
此机制通常适用于出现错误,例如忘记适当地初始化变量。但在这种情况下不是。那到底出了什么问题?
回到getmouse
声明。应该是:
sub getmouse(MEVENT:D) ...
:D
“type smiley”会告诉 Perl 6 参数必须是 defined,即 uninitialized NCurses::MEVENT
不够好。有了这个笑脸,你会得到一个适当的错误而不是沉默。
我没有成功从 getmouse
返回鼠标事件。我的代码有错误吗?
#!/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;
}
}
我找到了缺失的部分:
#!/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 = NCurses::MEVENT.new;
my $ok = getmouse( $event );
endwin;
say "ok: ", $ok.perl;
say "event: ", $event.perl;
exit;
}
}
一个不太令人敬畏的静默失败掩盖了您正在将类型对象传递到 getmouse() 的事实。我只是通过在第 18 行将 $event.perl
替换为 $event.x
来找到它作为信息钓鱼探险。这样做会产生;
user@Ubuntu-iMac:~$ ./getmouse.p6
ok: -1
Invocant requires an instance of type NCurses::MEVENT, but a type object was passed. Did you forget a .new?
in block at ./getmouse.p6 line 17
...这只是提供了更多信息。
我相信你现在明白了,但是,为了记录,你输入了 $event 变量但没有给它赋值,所以它得到了根据 Perl6 class tutorial 的类型对象是一个未定义的 "empty instance" 类型。
通过简单地将第 13 行的 my NCurses::MEVENT $event;
替换为 my $event = NCurses::MEVENT.new;
,可以得到;
user@Ubuntu-iMac:~$ ./getmouse.p6
ok: 0
event: NCurses::MEVENT.new(id => 0, x => 70, y => 26, z => 0, bstate => 128)
...世界一切都好。
常用成语
如果您必须将类型名称写为变量声明的一部分,您不妨将其写为变量的类型约束并使用 .= new
而不是使用 Marty 或您的解决方案:
my NCurses::MEVENT $event .= new
马蒂的解决方案:
my $event = NCurses::MEVENT.new
起作用是因为 $event
现在包含 getevent($event)
调用需要它包含的内容,即一个新的 NCurses::MEVENT 对象。但是它放弃了一个简单的机会来添加类型检查。
您的解决方案:
my NCurses::MEVENT $event = NCurses::MEVENT.new
的意思与这种情况下的常用习语相同,但不是 DRY。
出了什么问题
line of code that glues the Perl 6 getmouse
call to the underlying native NCurses library开始:
sub getmouse(MEVENT) ...
这告诉 Perl 6 getmouse 需要一个 NCurses::MEVENT
.
马蒂的解决方案奏效了。他们没有告诉 Perl 6 $event
应该包含什么类型的值。但是他们无论如何都会在其中放入正确的值,因此缺少类型检查并不重要。
您的原始解决方案启用了有用的类型检查。它告诉 Perl 6 确保 $event
只包含一个 NCurses::MEVENT
类型的对象。不幸的是,您没有显式初始化变量,因此它包含...
等一下。它包含什么? Perl 6 不应该确保 $event
中有一个 NCurses::MEVENT
对象吗?
事实上它做到了!但是 Perl 6 并没有将 ordinary new NCurses::MEVENT
对象放入其中,而是将旧的 NCurses::MEVENT
type 对象放入其中一个占位符。除其他事项外,Type 对象表示未初始化对象的概念。 (有点像 Perl 5 中的“undef”。)
此机制通常适用于出现错误,例如忘记适当地初始化变量。但在这种情况下不是。那到底出了什么问题?
回到getmouse
声明。应该是:
sub getmouse(MEVENT:D) ...
:D
“type smiley”会告诉 Perl 6 参数必须是 defined,即 uninitialized NCurses::MEVENT
不够好。有了这个笑脸,你会得到一个适当的错误而不是沉默。