在Tcl中传递特定对象的方法作为输入参数

时间:2017-01-19 08:30:01

标签: oop tcl metadata proc

我正在编写一个EDA实用程序,依赖于符合TCL 8.6的API。我的挑战如下:
我的实用程序运行在数据库中的晶体管模型上,并使用EDA供应商的TCL API命令进行一些分析。我可以向TCL命令传递一个TCL过程名称/指针,分析将依赖于我的代码,而不是EDA供应商的代码。内部写入过程接受指向EDA供应商数据库中特定晶体管实例的指针作为参数。 现在,EDA供应商允许使用TCL 8.6,这意味着我想传递而不是全局proc名称或命名空间proc名称,特定对象名称的名称/指针。我怎么做?在代码示例中:

oo:class create foo {
   constructor {} {
      variable numy 2
   }
   method fooshta { mos_pointer } {
      puts "now in mosy [get name $mos_pointer ]"
   }
   destructor {}
}
foo create bar
analyse_tx -proc < how do I refer to bar's method fooshta?>

在非OOP上下文中,代码如下所示:

proc fooshta { mos_pointer } {
      puts "now in mosy [get name $mos_pointer ]"
   }
 analyse_tx -proc fooshta


可以看出,我正在寻找 < how do I refer to bar's method fooshta, so that the EDA tool will invoke it for each transistors' instance? and pass the parameter?>的答案 感谢。

1 个答案:

答案 0 :(得分:1)

你不能,不能直接,至少不能,如果它将被这样调用:

$procname $thing_to_give_to_your_code

如果相反,它会被调用:

{*}$procname $thing_to_give_to_your_code

然后你可以通过传递 命令前缀 来实现它。

analyse_tx -proc [list bar fooshta]

这是我推荐的。如果调用是这样完成的,它也可能有效:

eval $procname [list $thing_to_give_to_your_code]

这种事情很棒,因为它还允许你传递绑定到apply的lambda术语等等。这是一个非常灵活的系统(因为它实际上是一个通用函数currying机制),它非常简单。

但是,如果您坚持使用这种调用方式:

$procname $thing_to_give_to_your_code

然后我们必须使用间接机制:内部解释器 别名 将让我们发出委托给命令的命令(是的,它会有一个名字)方法:

# The {} are to indicate that this command is aliasing from and to the current interpreter context
interp alias {} delegate-bar-fooshta {} bar fooshta

然后我们可以将delegate-bar-fooshta作为命令名称传递。如果你这么做很多,你可能应该把代理放在对象的命名空间上下文中;制作一个设置方法可能最容易:

oo::class create foo {
   constructor {} {
      variable numy 2
   }
   method fooshta { mos_pointer } {
      puts "now in mosy [get name $mos_pointer ]"
   }
   destructor {}

   method delegate {method args} {
      # We'll also bind in any extra arguments you choose to use
      interp alias {} [self namespace]::delegate-$method \
              {} [self] $method {*}$args
      return [namespace which delegate-$method]
   }
}

foo create bar
analyse_tx -proc [bar delegate fooshta]

通过这样做,使用常规机制杀死对象也将删除它拥有的委托命令。这在复杂的程序中非常方便,因为它会从你的脚本中将更多的家务杂事卸载到Tcl本身。