前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【100 种语言速成】第 6 节:Tcl/Tk

【100 种语言速成】第 6 节:Tcl/Tk

作者头像
海拥
发布2022-05-18 14:07:36
2.5K0
发布2022-05-18 14:07:36
举报
文章被收录于专栏:全栈技术全栈技术

给大家安利一个免费且实用的前端刷题(面经大全)网站,👉点击跳转到网站

是时候进行一些语言考古了!Tcl/Tk 是一种大家很少再看到的语言,但它在当时比较流行。它对嵌入非常友好——最初是一种用于编写现有应用程序的语言,而不是用于创建独立程序。它还带有内置的图形工具包(“Tk”部分),在它非常罕见的时候。

在新操作系统上安装 Tcl/Tk 是非常痛苦的。OSX 捆绑了一个过时的版本,当你运行一个 hello world 时会打印一个警告。要使用 brew 版本,我们必须使用 Tcl/Tk 可执行文件的完整路径(或弄乱$PATH)。

Unix shell 脚本

如果你熟悉 Unix shell 脚本,就更容易理解 Tcl/Tk。如果我们将语言放在类似 unix-shell 的尺度上,它会是这样的:

  • 传统的 Unix shell - 几乎不能用于编写代码
  • 现代的 Unix shell - 一些讨厌的控制结构,不适合真正的编程,但有些人还是强迫它。
  • Tcl/Tk - 它有资格作为一种真正的编程语言,但它看起来像 shell,并且有许多类似 shell 的语义
  • Perl - 在语法上它仍然看起来像 Unix shell,但它的行为更像是一种真正的编程语言
  • PHP - 仍然使用$印记,但仅此而已
  • Ruby - 如果你寻找它们,偶尔会出现类似 shell 的功能(如-nle, $.
  • Python - 几乎没有,除非你计算#评论

UNIXshell 脚本的工作方式是每一行都是一个命令-行的第一个单词是命令名,其余的是字符串参数。变量都只包含字符串-数字42和字符串“42”之间没有真正的区别。如果行包含任何$X,则在运行之前将其替换为变量 X 的字符串内容。TCL/TK 有点复杂,但这是一个很好的起点。

Hello World

代码语言:javascript
复制
#!/usr/local/opt/tcl-tk/bin/tclsh

puts "Hello, world!"

我是不是不小心放成了 Ruby 代码?不,绝对没有。#!指向完整路径的行是由于 OSX brew 问题,如果你在不同的系统上运行它,你将需要不同的系统。#也用于评论。

变量

代码语言:javascript
复制
#!/usr/local/opt/tcl-tk/bin/tclsh

set who "world"
puts "Hello, $who!"

变量都是字符串。内插双引号字符串。

需要注意的一件事是 $x 指变量的内容 x。

这是大多数语言没有的区别。即使在使用 sigils 的 Perl 或 PHP 中,也 $x 指变量(在=符号左侧)或其内容(在=符号右侧)。Shell 和 Tcl 对这两种情况进行了区分——它们没有 x=y 样式变量赋值。

类型

代码语言:javascript
复制
#!/usr/local/opt/tcl-tk/bin/tclsh

set x 2
set y "4"
set z [expr $x+$y]
puts [string toupper Hello]
puts [string tolower "World"]
puts "$x + $y = $z"
puts {$x + $y = $z}
puts stdout hello

输出

代码语言:javascript
复制
HELLO
world
2 + 4 = 6
$x + $y = $z
hello

变量都是字符串,所以 2 和 "2"都是一样的。你通常不需要引用它们,因此hello在"hello"大多数情况下,它们是相同的。

可以[function arguments]用来调用函数。[string action argument]是一个奇怪的函数,它根据它的参数执行许多操作,应用于第二个。如你所见,你是否通过 Hello 或"Hello".

要进行数学运算,你需要调用[expr …]函数。由于所有变量都是字符串,因此单独x+ y执行任何操作都没有任何意义。

{…}也是一个字符串,但不像"…"它不插入任何东西。Tcl 有许多看起来像控制结构的东西,但在某种程度上,它们只是传递包含代码的此类字符串。

而对于最后一个,puts hello 它本身应该可以工作,但是 puts 有可选参数在哪里打印它,当你输入puts helloTcl 时,如果你打算将 puts hello 字符串输出到标准输出,或者 puts 任何默认值到 hello 流中,你会感到困惑。也许我们不要想太多,我只是想提一下,hello 在"hello"大多数情况下几乎是一样的,但并非总是如此。

斐波那契

在大多数语言中,我们可以立即获得 Fibonacci 和 FizzBu​​zz,但对于 Tcl,我们必须在此之前采取一些额外的步骤。

代码语言:javascript
复制
#!/usr/local/opt/tcl-tk/bin/tclsh

proc fib n {
  if { $n <= 2 } {
    return 1
  } else {
    return [expr [fib [expr $n-1]] + [fib [expr $n-2]]]
  }
}

for {set i 1} {$i <= 30} {incr i} {
  puts [fib $i]
}

让我们一步一步来:

  • proc name arguments { … }定义一个函数。
  • for {set i 0} {$i < 30} {incr i} { … }在一个范围内循环,使用 C 风格 4-argument for。
  • incr i 增量 i,也可以通过 set i [expr $i + 1].
  • if { condition } { … } else { … }是一个条件 - 自动评估条件,无需额外[expr …]
  • return value 从函数返回

好的,看起来不错。除了那大多是谎言。{ }没有定义一个块,它只是我们传递的一个字符串。if, else, proc,return而不是关键字 - 它们只是命令。

所以这个糟糕的代码做同样的事情:

代码语言:javascript
复制
#!/usr/local/opt/tcl-tk/bin/tclsh

"proc" "fib" "n" {
  "if" { $n <= 2 } "return 1" "else" { "return" [expr ["fib" [expr $n-1]] + [fib ["expr" $n-2]]] }
}

"for" "set i 1" {$i <= 30} "incr i" { puts [fib $i] }

FizzBuzz

代码语言:javascript
复制
#!/usr/local/opt/tcl-tk/bin/tclsh

proc fizzbuzz n {
  if { $n % 15 == 0 } {
    return "FizzBuzz"
  } elseif { $n % 3 == 0 } {
    return "Fizz"
  } elseif { $n % 5 == 0 } {
    return "Buzz"
  } else {
    return $n
  }
}

for {set i 1} {$i <= 100} {incr i} {
  puts [fizzbuzz $i]
}

Tk Hello World

这是 GUI hello world:

代码语言:javascript
复制
#!/usr/local/opt/tcl-tk/bin/wish

wm geometry . 800x600
button .hello -text "Hello, World!" -command { exit }
pack .hello

这是它的样子:

在这里插入图片描述
在这里插入图片描述

请注意可执行文件从 更改tclsh为wish。

这与浏览器的工作方式非常不同。我们没有在某些标记中定义应用程序的结构,并且有代码来控制它——我们只是发出命令来直接控制 GUI:

wm geometry . 800x600- 将窗口大小设置为 800x600 button .name -text “…” -command {…}- 使用给定的文本和给定的 onclick 命令创建按钮,并将其保存到变量name pack .name- 将小部件放在name窗口中(默认水平居中,在顶部)

Tk 计数器

接下来让我们实现点击计数器:

代码语言:javascript
复制
#!/usr/local/opt/tcl-tk/bin/wish

set counter 0
proc plus_one args {
  global counter
  incr counter
}
proc minus_one args {
  global counter
  set counter [expr $counter-1]
}

wm geometry . 800x600
label .counter -textvariable counter -font "Helvetica -64"
button .plus -text "+1" -command plus_one -font "Helvetica -48"
button .minus -text "-1" -command minus_one -font "Helvetica -48"

place .counter -x 400 -y 200 -anchor s
place .minus -x 400 -y 300 -anchor e
place .plus -x 400 -y 300 -anchor w

这是它的样子:

在这里插入图片描述
在这里插入图片描述

让我们回顾一下:

  • 我们将计数器保存在全局变量中 counter
  • 我们有程序 plus_one 并且 minus_one 递增和递减计数器,因为变量默认是本地的,我们需要明确告诉它global counter 它们是为了修改全局变量 -incr 否则甚至会创建一个新的局部变量
  • 我们创建一个标签 --textvariable 参数使其在指定的全局变量更改时更新
  • -command { … }我们创建了一对按钮来调用我们的函数——我们也可以把整个函数放在里面
  • 所有这些的样式都是作为一些额外的参数传递-font 的,没有什么像 CSS
  • 我们使用命令将它们放置在窗口的特定点 place- 它接受-x -y 参数指定放置东西的位置,并-anchor指定将小部件放在锚点的哪一侧 - 似乎没有任何居中

Tcl/Tk 值得使用吗?

2021 年不是真的。对于常规编程,实际上有数百种更好的编程语言。对于嵌入式应用,我认为几乎每个人都转向 JavaScript、Lua 或 Python 等,或者基本上是 Tcl/Tk 以外的任何东西。

至于你的 shell 脚本的快速 GUI,Tk 是一个相当糟糕的工具包,我在我的 Electron Adventures 系列中介绍了许多更好的工具包。但即使你真的想使用 Tk,不知何故,由于历史原因, Ruby 和 Python 等许多现代语言在其标准库中仍然包含某种 Tk 代码。

Tcl/Tk 实际上只是作为一种历史产物感兴趣,而不是作为一种任何人都可能认真用于新软件的语言。

我什至很难说它对其他语言和 GUI 系统有多大影响。大多数 Tcl 特性也可以在 Unix shell 脚本和比 Tcl 早几个月发布的 Perl 中找到。因此,Unix shell 或 Perl 的影响可以更好地解释任何相似之处。旧风格的 GUI 几乎被浏览器风格的 GUI 所取代,所以我无法判断 Tk 是否对其他 GUI 工具包影响很大。在我看来,它基本上过期了,没有任何实际影响。有些语言已经过去了,但留下了很多遗产——就像大多数 ES6+ JavaScript 特性都来自 CoffeeScript;Perl 对几乎所有后 Perl 语言都产生了巨大的直接或间接影响。对于 Tcl/Tk,我真的没有看到类似的东西。它做了它的事,然后它就静静地死去,现在它几乎被遗忘了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Unix shell 脚本
  • Hello World
  • 变量
  • 类型
  • 斐波那契
  • FizzBuzz
  • Tk Hello World
  • Tk 计数器
  • Tcl/Tk 值得使用吗?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档