与TCL合作,我想实施类似Strategy Pattern的东西。我想通过TCL功能打印输出的“策略”,所以我可以轻松地在打印到屏幕和打印到日志文件之间切换。在TCL中做这件事的最好方法是什么?TCL是否有一些函数指针的概念?
回答
TCL允许您将过程的名称存储在变量中,然后使用该变量调用该过程;所以
proc A { x } {
puts $x
}
set strat A
$strat Hello
将调用程序A并打印出您好
如何使用可变函数?我不记得了TCL(它已经有一段时间...),但也许这些人会做你的需要:
- [$ VAR参数1参数2]
- [$ VAR]参数1参数2
- $ var param1 param2
如果我错了,任何人都可以自由纠正我。
这是你应该使用的最后一个。 – 2008-10-31 14:24:04
稍微扩大了什么上面列出的可能说明了策略模式更清晰的例子:
proc PrintToPDF {document} {
<snip logic>
}
proc PrintToScreen {document} {
<snip logic>
}
proc PrintToPrinter {document} {
<snip logic>
}
set document "my cool formatted document here"
set printMethod "printer"
switch -- $printMethod {
"printer" {
set pMethodName "PrintToPrinter"
}
"pdf" {
set pMethodName "PrintToScreen"
}
"screen" {
set pMethodName "PrintToPDF"
}
}
$pMethodName $document
除显示如何将过程分配给变量的答案,还可以将过程的名称作为参数传递给另一个过程。这里有一个简单的例子:
proc foo { a } {
puts "a = $a"
}
proc bar { b } {
puts "b = $b"
}
proc foobar { c } {
$c 1
}
foobar foo
foobar bar
这将打印= 1,B = 1
解释,为什么杰克逊的方法工作,记得在TCL,一切是一个字符串。无论你使用的是文字字符串,函数,变量还是其他任何东西,所有的都是一个字符串。您可以像“数据指针”一样传递“函数指针”:只需使用不带前导“$”的对象名称即可。
除了使用proc之外,您实际上可以使用代码块。这有几个变化。首先是最明显的,只是eval
而已。
set strategy {
puts $x
}
set x "Hello"
eval $strategy
unset x
这个工程,但有几个缺点。首先显而易见的是,这两部分代码必须混合使用一个通用的命名参数。这取代了一个命名空间头痛(procs)与另一个(本地人),这可以说实际上是更糟糕的。
不太明显的是,eval故意在不编译字节码的情况下解释它的参数。这是因为假设eval将被动态生成,通常是唯一的参数来调用,并且如果字节码只能被使用一次,相对于立即解释块而言,编译为字节码将是低效的。这是比较容易解决,所以这里的成语:
set x "Hello"
if 1 $strategy
unset x
if
,不像eval
,并编译和缓存的代码块。如果$strategy
块只有一个或只有少数不同的可能值,那么这个工作就很好。
这并不能解决将局部变量传递给模块的麻烦。有很多方法,比如像substitutions一样使用tk替换命令参数%
's。你可以尝试使用uplevel
或upvar
做一些骇人的事情。例如,你可以这样做:
set strategy {
puts %x
}
if 1 [string map [list %% % %x Hello] $strategy]
上关的机会,传递的参数不发生很大的变化,这非常适用于字节码编译的条款。另一方面,如果参数经常变化,则应使用eval
而不是if 1
。无论如何,就论据而言,这并不是好得多。由于您使用了特殊的语法,所以传递的内容和不传递的内容不太可能混淆。如果您想在返回代码块之前使用变量替换,这也很有用:如在set strategy "$localvar %x"
中。
幸运的是,tcl 8.5有true anonymous functions,使用apply
命令。 apply命令的第一个单词是参数和主体的列表,就像proc
的参数已被解除一样。其余参数立即作为参数传递给匿名命令。
set strategy [list {x} {
puts $x
}]
apply $strategy "Hello"
+1 for Tcl 8.5 information – 2009-07-25 04:59:01
% set val 4444
4444
% set pointer val
val
% eval puts $$pointer
4444
% puts [ set $pointer ]
4444
% set tmp [ set $pointer ]
4444
- 1. C中函数指针的概念?
- 2. Actionscript-Javascript中的C++指针的概念
- 3. mysql函数概念
- 4. 概念在C指针不明确
- 5. 一些逻辑OOP概念
- 6. ASP.NET MVC是否具有App_Code概念?
- 7. Oracle是否有过滤索引概念?
- 8. iPhone SDK中是否有Android Intent概念
- 9. R中有快捷方式/别名/指针的概念吗?
- 10. 微妙的指针和数组的概念
- 11. C++概念:一些签名函数转换
- 12. 线程上的一些概念问题
- 13. 一些基本的oracle概念
- 14. 关于Mulesoft的一些概念问题
- 15. 依赖注入中的一些概念
- 16. 函数指针指向一个函数指针的函数
- 17. PHP OOPS概念所需的一些指令
- 18. PowerShell中是否有函数指针或函数数组?
- 19. python是否有一个会话变量的概念?
- 20. JavaScript中的延期/承诺概念是一种新概念还是传统的函数式编程?
- 21. XSLT是否有任何数组的概念?
- 22. MySQL是否具有“this”数据库的概念?
- 23. 检查一个指针是否有一些字符串C++
- 24. 试图了解一些Java概念
- 25. C++中的虚函数的概念
- 26. 是否有ZODB一个主键概念对象
- 27. 3D编程概念指南?
- 28. 是否可以定义一个指向构造函数的函数指针?
- 29. ç递归函数调用的概念
- 30. 什么是概念?
,如果你的问题是关于执行该战略格局不要问在TCL函数指针。 – JesperE 2008-10-31 13:24:31