注意這個變化:
- Removed the encoding alias
binary
toiso8859-1
在 Tcl 9 之前的寫法是 -encoding binary。但是在 Tcl 9 之後如果使用 -encoding binary,會出現一個警告,如果要與之前的語義相同,要將 binary 改為 iso8859-1。下面是一個使用的例子:
fconfigure $fd -blocking 1 -encoding iso8859-1 -translation binary
關於各種 Tcl/Tk 的資訊,以及 Tcl/Tk 各種使用上的記錄分享
注意這個變化:
binary
to iso8859-1
在 Tcl 9 之前的寫法是 -encoding binary。但是在 Tcl 9 之後如果使用 -encoding binary,會出現一個警告,如果要與之前的語義相同,要將 binary 改為 iso8859-1。下面是一個使用的例子:
fconfigure $fd -blocking 1 -encoding iso8859-1 -translation binary
Tcl 9.0 的其中一個改變,就是移除了 --disable-threads 編譯選項,所以從 9.0.0 開始都會是 thread-enabled。不過也因為如此,如果你使用下列的方式檢查:
expr {[info exists ::tcl_platform(threaded)] && $::tcl_platform(threaded)}
在 Tcl 9 會得到答案為 0,因為 ::tcl_platform(threaded) 在 Tcl 9 中並不存在。
所以我改寫如下:
#
# Check support thread or not
#
proc is_threaded {} {
# Tcl 9 always thread-enabled
if {[package vcompare [info patchlevel] "9.0"] < 0} {
return [expr {[info exists ::tcl_platform(threaded)] && $::tcl_platform(threaded)}]
} else {
return 1
}
}
目前暫時先這樣,如果有更好的寫法我再更改寫法。
2024/11/16 更新寫法,嘗試使用 package vcompare 來比對版本號。
Tcl/Tk 釋出了一個新的主要版本,9.0.0。
Tcl/Tk 9.0 的主要改變可以參考官網的網頁,以及 tcl-release-notes-9.0.0.md, tk-release-notes-9.0.0.md。
主要是整合來自 AndroWish project 的 source code,以及更新了 stb_image_resize2.h。
有點麻煩的地方是,AndroWish 有加入了 TkPhoto 相關的程式,並且使用動態載入的方式載入 Tk。但是這個套件一開始的目的就是希望能在沒有 Tk 的情況下使用 stb image 方面的功能;所以我目前並沒有整合 TkPhoto 這部份的程式。
Tklib is like Tcllib, a collection of many small packages providing utilities, except that packages here are expected to depend on Tk. Tklib specializes in utilities for GUI programming.
The race to replace Redis
redis (Tcler's Wiki)
雖然有點晚了(在三月發生的事情),不過事件持續中。Redis 資料庫更改授權,從 7.4 開始就不是 Open Source 軟體。Redeis 目前使用雙授權,其中 Server
Side Public License (SSPL) 與 MongoDB 所使用的相同,不是 OSI 所認證的自由軟體授權(Redis 另外一個授權也不是!)。也因此有好幾個 Forks 出現,而各個 Linux distribution 需要找出可用的選項。
所以如果有人寫文章列出 Open Source Database,結果有 MongoDB(接下來 Redis 也是如此),你就知道這個文章的作者真的只是搜尋網路然後列出個名單,而他並不用心。
下面的程式使用 TclCurl 自網站下載 ATOM XML 的資料, 下載以後使用 tDom 分析並且將 title 與 link 的資料儲存為 html 格式。 只有使用自己的部落格資料測試過。
#!/usr/bin/env tclsh
package require TclCurl
package require tdom
proc get_atom {url} {
try {
set curlHandle [curl::init]
$curlHandle configure -url $url -bodyvar result
$curlHandle setopt CURLOPT_HTTP_VERSION 2TLS
catch { $curlHandle perform } curlErrorNumber
if { $curlErrorNumber != 0 } {
throw error [curl::easystrerror $curlErrorNumber]
}
} on error {em} {
error "Error: $em"
} finally {
$curlHandle cleanup
}
return $result
}
proc parse {XML ofname} {
set doc [dom parse $XML]
set root [$doc documentElement]
set ns {xmlns http://www.w3.org/2005/Atom}
$doc selectNodesNamespaces $ns
set titleList [$root selectNodes //xmlns:entry/xmlns:title]
set linkList [$root selectNodes {//xmlns:entry/xmlns:link[@rel='alternate']}]
set out [open $ofname w 0666]
foreach tnode $titleList lnode $linkList {
set ntitle [$tnode text]
set nlink [$lnode getAttribute href]
puts $out "<a href=\"$nlink\">$ntitle</a><br>"
}
close $out
}
if {$argc == 2} {
set url [lindex $argv 0]
set ofile [lindex $argv 1]
} else {
puts "Usage:"
puts "\ttclsh atom2html.tcl url filename"
exit
}
if {[catch {set data [get_atom $url]} err]} {
puts $err
} else {
parse $data $ofile
}
Eclipse Mosquitto 是一套開放原始碼的 MQTT Broker。
在 openSUSE 安裝:
sudo zypper in mosquitto
如果要執行的話,使用 systemctl 啟動服務:
sudo systemctl start mosquitto
再來使用 tcl.mqttc 驗證是否可以正確連線。
Subscribe:
package require mqttc
mqttc client "tcp://localhost:1883" "USERSSub" 1 -cleansession 1
client subscribe "MQTT Examples" 1
while 1 {
if {[catch {set result [client receive]}]} {
puts "Receive error!!!"
break
}
if {[llength $result] > 0} {
puts "[lindex $result 0] - [lindex $result 1]"
if {![string compare -nocase [lindex $result 1] "Exit"]} {
break
}
}
}
client unsubscribe "MQTT Examples"
client close
Publish:
package require mqttc
mqttc client "tcp://localhost:1883" "USERSPub" 1 -timeout 1000
client publishMessage "MQTT Examples" "Hello MQTT!" 1 0
client publishMessage "MQTT Examples" "Exit" 1 0
client close
先執行 Subscribe 的部份,再使用 Publish 發送訊息,確定可以正確執行。
下面是另外一個使用 tcl.mqttc 測試 Subscribe 與 Publish 功能的測試程式:
package require Thread
package require mqttc
catch {console show}
set ::gThread [thread::create {thread::wait} ]
set result 0
proc subscribe { } {
thread::send -async $::gThread {
package require mqttc
mqttc client "tcp://localhost:1883" "USERTest1" 1 -cleansession 1
client subscribe "MQTT Examples" 1
while 1 {
if {[catch {set result [client receive]}]} {
puts "Receive error!!!"
break
}
if {[llength $result] > 0} {
puts "[lindex $result 0] - [lindex $result 1]"
if {![string compare -nocase [lindex $result 1] "Exit"]} {
break
}
}
}
client unsubscribe "MQTT Examples"
client close
} ::result
}
subscribe
puts "started test..."
after 250
mqttc client "tcp://localhost:1883" "USERTest2" 1 -timeout 1000
client publishMessage "MQTT Examples" "Hello MQTT!" 1 0
client publishMessage "MQTT Examples" "Exit" 1 0
client close
vwait ::result