如何执行作为引用存储在散列 table 中的 Tk-Canvas 函数?
How do I execute a Tk-Canvas function stored as a reference in a hash table?
我正在尝试执行一个存储为散列函数引用的 Tk 函数 table。在下面的非常简化的示例中,代码应绘制一个大红点(即执行第 14 行的操作)。我无法对 createOval() 进行有效引用,无论是在散列 table 中使用 $w->,还是将其向下移动到第 13 行。我已经用谷歌搜索了这个高点和低点,但无济于事.我错过了什么?
如果我将 $w->... 作为参考,错误消息是 "wrong number of args: ..." 如果我在第 10 行的 $w 前面填充 \&:"Not a CODE reference at a11.pl line 9."
这在 Python 中非常容易做到:只需将 w.create_oval 填入字典即可。
use strict;
use warnings;
use Tk;
my $mw = MainWindow->new;
my $w = $mw->Canvas(-width => 1200, -height => 800);
$w->pack;
my %xfun = (
'b' => $w->createOval
);
$xfun{'b'}(200, 200, 250, 250, -fill=>'red');
#$w->createOval(200, 200, 250, 250, -fill=>'red');
MainLoop;
以下似乎有效:
use strict;
use warnings;
use Tk;
my $mw = MainWindow->new;
my $w = $mw->Canvas(-width => 1200, -height => 800);
$w->pack;
my %xfun = (
b => sub { $w->createOval(@_); },
);
$xfun{b}->(200, 200, 250, 250, -fill=>'red');
MainLoop;
注:
我假设你原来的电话:
$xfun{'b'}(200, 200, 250, 250, -fill=>'red');
没有工作,因为它错过了对象 $w
作为第一个参数,但是当我
尝试将 $w
作为第一个参数显式传递:
$xfun{'b'}($w, 200, 200, 250, 250, -fill=>'red');
它仍然没有用..我得到错误:
wrong # args: should be ".canvas create oval coords ?arg arg ...?"
If I treat $w->... as a reference, the error message is "wrong number of args: ..."
我不知道你所说的"treat as a reference"是什么意思。
您的代码无法按编写的方式运行,因为 $w->createOval
是一个没有参数的方法调用,与 $w->createOval()
相同。
使用 \&$w->createOval
时,它解析为 \((&$w)->createOval)
,这与 \($w->(@_)->createOval)
:
(大部分)相同
- 将
$w
作为代码参考并使用当前参数列表调用它,@_
(这是您的错误发生的地方,因为$w
实际上是一个对象)
- 获取 return 值并对其调用
createOval
方法
- 参考
createOval
的return值
您可以使用 $w->can('createOval')
获取对 createOval
子项的引用,但这对您没有帮助,因为那只是函数(没有对象)。要调用它,您必须显式传入 $w
作为第一个参数(这在方法调用中隐式发生):
my %xfun = (
'b' => $w->can('createOval'),
);
$xfun{'b'}($w, 200, 200, 250, 250, -fill=>'red');
最直接的解决方案是 b => sub { $w->createOval(@_) }
,即将方法调用包装在转发其参数的代理子中。
我正在尝试执行一个存储为散列函数引用的 Tk 函数 table。在下面的非常简化的示例中,代码应绘制一个大红点(即执行第 14 行的操作)。我无法对 createOval() 进行有效引用,无论是在散列 table 中使用 $w->,还是将其向下移动到第 13 行。我已经用谷歌搜索了这个高点和低点,但无济于事.我错过了什么?
如果我将 $w->... 作为参考,错误消息是 "wrong number of args: ..." 如果我在第 10 行的 $w 前面填充 \&:"Not a CODE reference at a11.pl line 9."
这在 Python 中非常容易做到:只需将 w.create_oval 填入字典即可。
use strict;
use warnings;
use Tk;
my $mw = MainWindow->new;
my $w = $mw->Canvas(-width => 1200, -height => 800);
$w->pack;
my %xfun = (
'b' => $w->createOval
);
$xfun{'b'}(200, 200, 250, 250, -fill=>'red');
#$w->createOval(200, 200, 250, 250, -fill=>'red');
MainLoop;
以下似乎有效:
use strict;
use warnings;
use Tk;
my $mw = MainWindow->new;
my $w = $mw->Canvas(-width => 1200, -height => 800);
$w->pack;
my %xfun = (
b => sub { $w->createOval(@_); },
);
$xfun{b}->(200, 200, 250, 250, -fill=>'red');
MainLoop;
注:
我假设你原来的电话:
$xfun{'b'}(200, 200, 250, 250, -fill=>'red');
没有工作,因为它错过了对象 $w
作为第一个参数,但是当我
尝试将 $w
作为第一个参数显式传递:
$xfun{'b'}($w, 200, 200, 250, 250, -fill=>'red');
它仍然没有用..我得到错误:
wrong # args: should be ".canvas create oval coords ?arg arg ...?"
If I treat $w->... as a reference, the error message is "wrong number of args: ..."
我不知道你所说的"treat as a reference"是什么意思。
您的代码无法按编写的方式运行,因为 $w->createOval
是一个没有参数的方法调用,与 $w->createOval()
相同。
使用 \&$w->createOval
时,它解析为 \((&$w)->createOval)
,这与 \($w->(@_)->createOval)
:
- 将
$w
作为代码参考并使用当前参数列表调用它,@_
(这是您的错误发生的地方,因为$w
实际上是一个对象) - 获取 return 值并对其调用
createOval
方法 - 参考
createOval
的return值
您可以使用 $w->can('createOval')
获取对 createOval
子项的引用,但这对您没有帮助,因为那只是函数(没有对象)。要调用它,您必须显式传入 $w
作为第一个参数(这在方法调用中隐式发生):
my %xfun = (
'b' => $w->can('createOval'),
);
$xfun{'b'}($w, 200, 200, 250, 250, -fill=>'red');
最直接的解决方案是 b => sub { $w->createOval(@_) }
,即将方法调用包装在转发其参数的代理子中。