如何执行作为引用存储在散列 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(@_) },即将方法调用包装在转发其参数的代理子中。