原文:
13. What are some of the primary differences between Tcl/Tk and Perl/Tk?
Considering that both interpreters/(compiler) for Tcl and Perl were written in C for original use on Unix computers it is not surprising that there are some similarities between the two languages.
Nevertheless, there are a large number of differences between the Tcl language and the Perl language. One thing to keep in mind is that to build, install, and use Perl/Tk one does not need to have Tcl/Tk on hand at all. Perl/Tk is completely independent of Tcl/Tk.
Tom Christiansen (a definite perl proponent) has put up a web page that elucidates some critical technical differences between Tcl and Perl at: http://www.perl.com/perl/versus/tcl-discussion.html
Within each language there is Tk - a widget Toolkit. One must be careful that some of the Tcl/Tk widget names and options have been modified slightly in the perl/Tk language.
With Tk-b9.01 (and higher) a great many functions (method calls actually) start with an upper case letter and continue with all lower case letters (e.g. there is a perl/Tk Entry widget but no entry widget), and many configuration options are all lower case (e.g. there is a perl/Tk highlightthickness option but no highlightThickness option). Thus if you are having trouble converting a script check your typing. (there is a script b9names to help). There is also a tcl2perl script (discussed later).
The html docs that get created during the build of perl/Tk ought to help clarify most any language difference. While the following table does not cover all the differences it is hoped that it will prove useful, especially to those people coming from a primarily Tcl/Tk programming background. These are some of the common Tcl->Perl stumbling points: what Tcl/Tk Perl/Tkvariable set a 123 $a = 123; or $a = '123'; initializationre-assignment set b $a $b = $a;lists/arrays set a {1 2 fred 7.8} @a = (1,2,'fred',7.8);re-assignment list set b $a @b = @a;associative set a(Jan) 456.02 %a = ('Jan',456.02,'Feb',534.96); arrays set a(Feb) 534.96re-assignment foreach i \ %b = %a; [array names a] { set b($i) = $a($i) }Note on the above examples:In Tcl the scalar, list, and array variable 'a' will overwrite each previous assignment.In Perl $a, @a, %a are all distinct (occupy separate namespaces).expressions set a [expr $b+$c] $a = $b+$c;increment incr i $i++; or ++$i;declare proc plus {a b} { sub plus { my($a,$b) = @_; subroutines expr $a + $b } $a+$b; }variable scope local default global default override w/ "global" override w/ "my" (or "local")call plus 1 2 &plus(1,2); #or subroutines plus(1,2); #OK after sub plusstatement sep newline or at ";" ";" requiredstatement "" - newline none required continuationverbatim strings {} '' e.g. {a \ lot@ of $stuff} 'a \ lot@ of $stuff'escaped strings "" "" e.g. "Who\nWhat\nIdunno" "Who\nWhat\nIdunno"STDOUT puts "Hello World!" print "Hello World!\n" puts stdout "Hello!" print STDOUT "Hello!\n"
Note also that Tcl/Tk has a built-in abbreviation completion mechanism that lets you specify short hand, e.g. canvas .frame.canvas -yscrollcommand ".frame.scroll set" ; #Tcl/Tk OK canvas .frame.canvas -yscroll ".frame.scroll set" ; #Tcl/Tk also OK $canvas=$main->Canvas(-yscroll => ['set',$scroll]); #ERROR perl/Tk $canvas=$main->Canvas(-yscrollcommand => ['set',$scroll]); #perl/Tk OK
You may get around this with the perl abbrev.pl package in certain circumstances. For example: require 'abbrev.pl'; %foo = (); &abbrev(*foo,'-yscrollcommand'); ... $canvas=$main->Canvas($foo{'-yscroll'} => ['set',$scroll]); #perl/Tk OK
In Perl you can emulate the Tcl unknown proc (through the perl AUTOLOAD mechanism) as follows: use Shell; print($p = man(-k => bitmap));
Which is equivalent to what you would get if you typed: man -k bitmap
From within tclsh or wish. (Thanks to Ilya Zakharevich mailto:ilya@math.ohio-state.edu for pointing out this feature. ;-)
译文:
13. Tcl/Tk和Perl/Tk之间的主要区别是什么?
考虑到Tcl和Perl的解释器(编译器)都是用C语言写的,而且最初都是用于Unix系统,所以这两种语言之间有一些相似之处也就不足为奇了。
但是,Tcl语言和Perl语言之间还是存在很大差别的。大家必须清楚的是,要编译、安装和使用Perl/Tk完全不需要Tcl/Tk,也就是说,Perl/Tk是完全独立于Tcl/Tk的。
Tom Christiansen(一个忠实的Perl支持者)在下面的网页中说明了一些Tcl和Perl之间的主要的技术上的区别:
http://www.perl.com/perl/versus/tcl-discussion.html
在这两个语言中有Tk——即组件工具箱。因此,我们必须注意,一些Tcl/Tk的组件名称和选项在Perl/Tk语言中已经被稍作修改了。
在Tk -b9.01以后的版本中,大部分的函数(实际上应该叫做“方法”)都是以大写字母开头,后面跟着小写字母(例如,Perl/Tk中有Entry组件,但是没有entry组件)。而很多配置选项则都是小写字母(例如,Perl/Tk中有highlightthickness选项,但是没有 highlightThickness选项)。因此,如果你在把Tcl脚本转换成Perl/Tk脚本时出现问题,首先应该检查你的输入是否正确。其实,有一个叫做tcl2perl的脚本,这个我们将在后面讨论。
实际上,在Perl/Tk构建过程中产生的 html格式的文档应该对于阐明大部分的语言方面的区别很有帮助。下面的这个表格无法涉及两种语言之间所有的区别之处,这里我们只是希望它能有些用处—— 尤其对于是那些原本拥有Tcl/Tk编程背景的人。下面就是一些通常的Tcl和Perl之间的不同点:
含义 Tcl/Tk Perl/Tk
变量初始化 set a 123 $a = 123;或 $a = '123';
相互赋值 set b $a $b = $a;
列表/数组 set a {1 2 fred 7.8} @a = (1,2,'fred',7.8);
相互赋值 list set b $a @b = @a;
关联数组 set a(Jan) 456.02 %a = ('Jan',456.02,'Feb',534.96);
set a(Feb) 534.96
相互赋值 foreach i \ %b = %a;
[array names a] {
set b($i) = $a($i) }
这请注意,在上面的例子中:
Tcl语言里,标量、列表和数组变量’a’相互之间会覆盖。
但是,在Perl语言里$a、@a和%a是完全不同的(它们分属于不同的名称空间)。
表达式 set a [expr $b+$c] $a = $b+$c;
变量值增加 incr i $i++; or ++$i;
申明子程序 proc plus {a b} { sub plus { my($a,$b) = @_;
expr $a + $b } $a+$b; }
变量作用域 默认为“局部” 默认为“全局”
覆盖使用"global" 覆盖使用"my"(或"local")
调用子程序 plus 1 2 &plus(1,2);
subroutines 或 plus(1,2); #只要在plus申明之后就可以
语句分隔 新行或者分号";" 分号";"是必须的
语句续行 ""符号后面接新行 无特殊要求
字符串分隔符 {} ''
例子: {a \ lot@ of $stuff} 'a \ lot@ of $stuff'
插值字符串分隔 "" ""
例子 "Who\nWhat\nIdunno" "Who\nWhat\nIdunno"
标准输出 puts "Hello World!" print "Hello World!\n"
puts stdout "Hello!" print STDOUT "Hello!\n"
另外,请注意,在Tcl/Tk中有一种内置的“缩写补充完成机制”(abbreviation completion mechanism),这使得你可以使用缩写。例如:
canvas .frame.canvas -yscrollcommand ".frame.scroll set" ; #Tcl/Tk中可以
canvas .frame.canvas -yscroll ".frame.scroll set" ; #Tcl/Tk中也可以
$canvas=$main->Canvas(-yscroll => ['set',$scroll]); #Perl/Tk中将出错
$canvas=$main->Canvas(-yscrollcommand => ['set',$scroll]); #Perl/Tk中可以
在某些情况下在Perl中也可以使用这种机制,但是需要abbrev.p包。例如:
require 'abbrev.pl';
%foo = ();
&abbrev(*foo,'-yscrollcommand');
...
$canvas=$main->Canvas($foo{'-yscroll'} => ['set',$scroll]); #Perl/Tk中就可以了
(译者注:没用过,不过好麻烦哟……:<)
在Perl语言中,你可以通过Perl的AUTOLOAD机制来模拟Tcl的未知proc,如下:
use Shell;
print($p = man(-k => bitmap));
它的结果等价与你在tclsh或wish里输入:
man -k bitmap
(感谢Ilya Zakharevich为我们指出这个特性!)