我正在尝试执行存储为哈希表中函数的引用的Tk函数。在下面的简化示例中,代码应绘制一个大的红点(即执行第14行)。我不能对createOval()做出有效的引用,也不能使用$ w->在哈希表中,也没有向下移动到第13行。我已经google了这个高低,但无济于事。我错过了什么?
如果我将$ w-> ...视为参考,则错误消息是“错误的args数量:...”,如果我填充\&在第10行的$ w前面:“不是a11.pl第9行的CODE引用。”
在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;
答案 0 :(得分:3)
如果我将$ w-> ...视为参考,则错误消息为"错误的参数数量:..."
我不知道你的意思"作为参考"。
您的代码没有按照书面形式工作,因为<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<context:component-scan base-package="pl.spring.demo.entity" />
<jpa:repositories base-package="pl.spring.demo.repository" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!--<util:properties id="hsqldbJpaProps"location="classpath:/test_data_access/hsqldb_jpa.properties"
/> -->
<!--<jdbc:embedded-database id="dataSource" type="HSQL" /> -->
<bean name="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/gielda" />
<property name="username" value="root" />
<property name="password" value="starterkit" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="pl.spring.demo.entity" />
<property name="dataSource" ref="dataSource" />
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"> </bean>
</property>
</bean>
</beans>
是一个没有参数的方法调用,与$w->createOval
相同。
使用$w->createOval()
解析为\&$w->createOval
,其中(大部分)与\((&$w)->createOval)
相同:
\($w->(@_)->createOval)
视为代码引用,并使用当前参数列表$w
调用它(这是您的错误发生的地方,因为@_
实际上是一个对象)$w
方法createOval
您可以使用$w->can('createOval')
获取对createOval
子的引用,但这对您没有帮助,因为它只是函数(没有对象)。要调用它,您必须显式传入createOval
作为第一个参数(这在方法调用中隐式发生):
$w
最直接的解决方案是my %xfun = (
'b' => $w->can('createOval'),
);
$xfun{'b'}($w, 200, 200, 250, 250, -fill=>'red');
,即将方法调用包装在转发其参数的代理子中。
答案 1 :(得分:2)
以下似乎有效:
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');
没有用,因为它错过了第一个arg对象$w
,但是当我失败时
尝试明确地传递$w
作为第一个参数:
$xfun{'b'}($w, 200, 200, 250, 250, -fill=>'red');
它仍然无效..我收到了错误:
wrong # args: should be ".canvas create oval coords ?arg arg ...?"