Perl6:NCurses和鼠标事件
我没有成功从getmouse
返回鼠标事件。我的代码中是否有错误?Perl6:NCurses和鼠标事件
#!/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;
}
}
一个低于真棒无声故障屏蔽您传递一个类型的对象到getmouse(事实)。我只在第18行用$event.perl
代替$event.x
作为信息捕鱼的探险。这样做会产生;
[email protected]:~$ ./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
...这只是一点点更多的信息。
我敢肯定,你得到它,但现在,对于记录,您输入的$事件变量,但没有任何值分配给它,所以它得到了根据Perl6 class tutorial是一个未定义的类型的对象,“空实例“的类型。 只需在第13行用my $event = NCurses::MEVENT.new;
代替my NCurses::MEVENT $event;
即可;
[email protected]:~$ ./getmouse.p6
ok: 0
event: NCurses::MEVENT.new(id => 0, x => 70, y => 26, z => 0, bstate => 128)
......和一切都很好的世界。
我已经找到了缺失的部分:
#!/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;
}
}
常用的成语
如果你必须写一个类型的名字作为一个变量声明的一部分,你还不如把它写成变量的类型约束和使用.= new
而不是使用任何马蒂或解决方案:
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
对象吗?
其实它做到了!但不是把一个普通新的NCurses::MEVENT
对象在那里Perl 6把一个旧的NCurses::MEVENT
类型对象在那里作为占位符。除此之外,Type对象表示未初始化对象的概念。 (有点像Perl 5中的“undef”。)
这种机制通常适用于像忘记适当初始化变量一样的错误。但不是在这种情况下。那么出了什么问题?
回到getmouse
声明。它应该是:
sub getmouse(MEVENT:D) ...
的:D
“式的笑脸”会告诉Perl 6中的参数必须是定义,即一个未初始化NCurses::MEVENT
不够好。有了这个笑脸,你会得到一个适当的错误而不是沉默。
Raiph - 我想你会发现建议的'sub getmouse(MEVENT:D)'签名和你以前使用'。= new' __时的建议__当进行类型检查时.__我不同意你的意思该类型检查*应该*在任何地方使用。简而言之,几乎没有风险混淆类型和没有获得重大性能收益的小程序并不需要所有的检查和约束,是吗?我们不能偶尔骑在狂野的一面吗? ;-) – Marty
我不是暗示显式类型检查应该到处使用。编码人员可能不关心许多脚本的类型约束。但是,我列出的替代方案与您的解决方案完全相同,没有坏处,是通常的习惯用法,无论如何可能会发生类型错误,即使无关紧要,也可能会加速编码,并为编码器建立正确的编码模式*确实*关心速度或捕捉类型错误。 TIMTOWTDIBSCINABTE。 :) – raiph
我已经在我的答案中更正了这一点。 –
是的 - 当发生这种情况时,我正在寻找解决方案并起草我的答案。非常感谢你接受我自己 - 我很高兴你自己找到了它 - 我只是希望你在半小时后就这么做了。 ;-) – Marty