#!/usr/bin/env tclsh
if {$argc >= 1} {
set name [lindex $argv 0]
} elseif {$argc == 0} {
set name "you"
}
puts "One for $name, one for me."
2019-11-28
Tcl: Two Fer
Create a sentence of the form "One for X, one for me.".
2019-11-17
Tcl: Group the strings to concatenate together
set s "Hello "
set t "Tcl"
set u "!"
puts $s$t$u
也可以先設到某個變數,再印出來:
set s "Hello "
set t "Tcl"
set u "!"
set str $s$t$u
puts $str
感覺還蠻有趣的。
2019-11-13
Twitter feed for news and Tcl
@TclLang - Twitter feed for news about happenings in the Tcl world.
我之前沒注意到,這是 Tclers's wiki 的官方帳號嗎?不是很確定。
我之前沒注意到,這是 Tclers's wiki 的官方帳號嗎?不是很確定。
2019-10-29
tablelist 6.7
ANNOUNCE: Multi-column listbox and tree widget package Tablelist 6.7
Tablelist 釋出了一個新版 6.7,所以我也更新了自己的 RPM spec 測試。
Tablelist 釋出了一個新版 6.7,所以我也更新了自己的 RPM spec 測試。
2019-09-19
RabbitMQ/MQTT
RabbitMQ 是實現進階訊息佇列協議 AMQP (Advanced Message Queuing Protocol) 的中間件軟體,
支援的協議版本為 0.9.1,也有 plugin 可以支援 1.0。
官網上有提供安裝檔案可以使用,如果在 openSUSE 15.1,可以使用下列的指令安裝:
如果要啟動服務,可以使用下列的指令:
如果要重啟服務,可以使用下列的指令:
如果知道服務的狀態,可以使用下列的指令:
如果要停止服務,可以使用下列的指令:
RabbitMQ 有支援 MQTT 3.1 的 plugin。下面是啟用的方式(啟用後需要重開 server 才會生效):
設定檔案在 /etc/rabbitmq/rabbitmq.conf,因為只是要測試,所以我把 port 改為 1883,啟用預設的 username/password, 並且關閉允許匿名連線:
下面是使用 tcl.mqttc 測試 Subscribe 與 Publish 功能的測試程式:
官網上有提供安裝檔案可以使用,如果在 openSUSE 15.1,可以使用下列的指令安裝:
sudo zypper in rabbitmq-server rabbitmq-server-plugins
如果要啟動服務,可以使用下列的指令:
sudo service rabbitmq-server start
如果要重啟服務,可以使用下列的指令:
sudo service rabbitmq-server restart
如果知道服務的狀態,可以使用下列的指令:
sudo service rabbitmq-server status
如果要停止服務,可以使用下列的指令:
sudo service rabbitmq-server stop
RabbitMQ 有支援 MQTT 3.1 的 plugin。下面是啟用的方式(啟用後需要重開 server 才會生效):
sudo rabbitmq-plugins enable rabbitmq_mqtt
設定檔案在 /etc/rabbitmq/rabbitmq.conf,因為只是要測試,所以我把 port 改為 1883,啟用預設的 username/password, 並且關閉允許匿名連線:
## ----------------------------------------------------------------------------
## RabbitMQ MQTT Adapter
##
## See https://github.com/rabbitmq/rabbitmq-mqtt/blob/stable/README.md
## for details
## ----------------------------------------------------------------------------
# =======================================
# MQTT section
# =======================================
## TCP listener settings.
##
mqtt.listeners.tcp.1 = 127.0.0.1:1883
mqtt.listeners.tcp.2 = ::1:1883
## TCP listener options (as per the broker configuration).
##
# mqtt.tcp_listen_options.backlog = 4096
# mqtt.tcp_listen_options.recbuf = 131072
# mqtt.tcp_listen_options.sndbuf = 131072
#
# mqtt.tcp_listen_options.keepalive = true
# mqtt.tcp_listen_options.nodelay = true
#
# mqtt.tcp_listen_options.exit_on_close = true
# mqtt.tcp_listen_options.send_timeout = 120
## TLS listener settings
## ## See https://rabbitmq.com/mqtt.html and https://rabbitmq.com/ssl.html for details.
#
# mqtt.listeners.ssl.default = 8883
#
# ssl_options.cacertfile = /path/to/tls/ca_certificate_bundle.pem
# ssl_options.certfile = /path/to/tls/server_certificate.pem
# ssl_options.keyfile = /path/to/tls/server_key.pem
# ssl_options.verify = verify_peer
# ssl_options.fail_if_no_peer_cert = true
#
## Number of Erlang processes that will accept connections for the TCP
## and TLS listeners.
##
# mqtt.num_acceptors.tcp = 10
# mqtt.num_acceptors.ssl = 10
## Whether or not to enable proxy protocol support.
## Once enabled, clients cannot directly connect to the broker
## anymore. They must connect through a load balancer that sends the
## proxy protocol header to the broker at connection time.
## This setting applies only to STOMP clients, other protocols
## like STOMP or AMQP have their own setting to enable proxy protocol.
## See the plugins or broker documentation for more information.
##
# mqtt.proxy_protocol = false
## Set the default user name and password used for anonymous connections (when client
## provides no credentials). Anonymous connections are highly discouraged!
##
mqtt.default_user = guest
mqtt.default_pass = guest
## Enable anonymous connections. If this is set to false, clients MUST provide
## credentials in order to connect. See also the mqtt.default_user/mqtt.default_pass
## keys. Anonymous connections are highly discouraged!
##
mqtt.allow_anonymous = false
## If you have multiple vhosts, specify the one to which the
## adapter connects.
##
mqtt.vhost = /
## Specify the exchange to which messages from MQTT clients are published.
##
mqtt.exchange = amq.topic
## Specify TTL (time to live) to control the lifetime of non-clean sessions.
##
mqtt.subscription_ttl = 1800000
## Set the prefetch count (governing the maximum number of unacknowledged
## messages that will be delivered).
##
mqtt.prefetch = 10
下面是使用 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 \
-username guest -password guest
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 \
-username guest -password guest
client publishMessage "MQTT Examples" "Hello MQTT!" 1 0
client publishMessage "MQTT Examples" "Exit" 1 0
client close
vwait ::result
2019-09-10
tcl.mqttc v0.6
因為 paho.mqtt.c 有一個新的版本 1.3.1,所以我做了 tcl.mqttc 相關的更新,同時將版本設成 v0.6。
不過我只有測試 tcp 部份,使用 ActiveMQ 測試 MQTT 3.1,以及使用 EMQX 測試 MQTT 3.1 以及 5 的部份。
我忘記是不是有在這個部落格貼過了,下面是 MQTT 3.1 測試 Subscribe 與 Publish 功能的測試程式:
不過我只有測試 tcp 部份,使用 ActiveMQ 測試 MQTT 3.1,以及使用 EMQX 測試 MQTT 3.1 以及 5 的部份。
我忘記是不是有在這個部落格貼過了,下面是 MQTT 3.1 測試 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
2019-08-19
casstcl 2.13.2
2019-08-05
MAWT (Movie Automation With Tcl) 0.2.0
MAWT - Movie Automation With Tcl 已經在 2019/06/20 釋出了 0.2.0。
0.2.0 更新的資訊:
Improved video generation functionality.
所以我也更新了我自己的 openSUSE 套件。
0.2.0 更新的資訊:
Improved video generation functionality.
所以我也更新了我自己的 openSUSE 套件。
2019-06-08
Tclsh and Here document
Here document
之前我只有在 bash 使用過,今天突然間想試看看 tclsh。我發現…… 對,可以使用同樣的手法。下面就是一個測試的例子:
再來是另外一個簡單的測試:
這樣就可以在命令列執行簡單的 tclsh 命令。
之前我只有在 bash 使用過,今天突然間想試看看 tclsh。我發現…… 對,可以使用同樣的手法。下面就是一個測試的例子:
tclsh - << "EOF"
puts "HELLO World"
EOF
再來是另外一個簡單的測試:
tclsh - << "EOF"
puts [expr 99 + 1]
EOF
這樣就可以在命令列執行簡單的 tclsh 命令。
2019-06-02
Functional Programming
Functional Programming (Tcler's Wiki)
Tcl 是個很奇妙的語言,就如同下面說的:
As with many things, Tcl is rather unique in this area. Commands themselves can not be passed as arguments to other commands, but their names can, which provides something very similar to first-class functions. Additionally, apply can be used to interpret a value as a function and evaluate it, providing the equivalent of lambda functions.
Tcl 的表達方式與波蘭表示法 (Polish notation) 一樣,和 Lisp 的 S-expression 的精神十分相像,特點是操作符置於操作數的前面(就是如果是一連串資料所組合成的述句,Tcl 述句的第一個是一個 command,後面是 command 要處理的資料)。
Tcl 也跟 Lisp 一樣,並不是純粹的 Functional Language,而是支援多重典範的語言。
Tcl 是個很奇妙的語言,就如同下面說的:
As with many things, Tcl is rather unique in this area. Commands themselves can not be passed as arguments to other commands, but their names can, which provides something very similar to first-class functions. Additionally, apply can be used to interpret a value as a function and evaluate it, providing the equivalent of lambda functions.
Tcl 的表達方式與波蘭表示法 (Polish notation) 一樣,和 Lisp 的 S-expression 的精神十分相像,特點是操作符置於操作數的前面(就是如果是一連串資料所組合成的述句,Tcl 述句的第一個是一個 command,後面是 command 要處理的資料)。
Tcl 也跟 Lisp 一樣,並不是純粹的 Functional Language,而是支援多重典範的語言。
2019-05-24
Tcl: 奇數和偶數
#!/usr/bin/env tclsh
puts -nonewline "Please input a number: "
flush stdout
gets stdin var
if { [ regexp {^[0-9]+$} $var ] == 0} {
puts "It is not a number!!!"
exit
}
if { [expr $var % 2] == 0} {
puts "It is even!!!"
} else {
puts "It is odd!!!"
}
也是一個很簡單的練習,只是使用正規表示式判斷是否為數字。
2019-05-21
Tcl:九九乘法表
這只是一個簡單的 Tcl 練習。
所以第一個是 for loop 的版本。
第二個版本是我在寫同樣的東西(也是九九乘法表),因為 Erlang 沒有 for 和 while 迴圈,所以我先建立一個 list,然後再使用 Erlang 提供的 lists:foreach 印出結果。我用同樣的精神寫 Tcl 九九乘法表的第二個版本(同時測試 mathop)。
最後是遞迴的版本:
所以第一個是 for loop 的版本。
#!/usr/bin/env tclsh
for {set nx 0} {$nx < 10} {incr nx} {
for {set ny 0} {$ny < 10} {incr ny} {
puts "[format "%d x %d = %2d" $nx $ny [expr $nx * $ny]]"
}
}
第二個版本是我在寫同樣的東西(也是九九乘法表),因為 Erlang 沒有 for 和 while 迴圈,所以我先建立一個 list,然後再使用 Erlang 提供的 lists:foreach 印出結果。我用同樣的精神寫 Tcl 九九乘法表的第二個版本(同時測試 mathop)。
#!/usr/bin/env tclsh
set x [list 1 2 3 4 5 6 7 8 9]
set y [list 1 2 3 4 5 6 7 8 9]
foreach nx $x {
foreach ny $y {
set z [::tcl::mathop::* $nx $ny]
puts "[format "%d x %d = %2d" $nx $ny $z]"
}
}
最後是遞迴的版本:
#!/usr/bin/env tclsh
namespace path {::tcl::mathop ::tcl::mathfunc}
proc mul {x y} {
puts [format "%d x %d = %2d" $x $y [* $x $y]]
if {$y < 9} {
mul $x [+ $y 1]
} else {
if {$x < 9} {
mul [+ $x 1] 1
} else {
return
}
}
}
mul 1 1
2019-05-13
Next Scripting Framework 2.3.0
ANNOUNCE: Next Scripting Framework 2.3.0 is available
NSF 釋出了 2.3.0,所以我更新了我自己的 openSUSE RPM spec, 這可以比較方便進行測試。我在下載的時候 SourceForge 似乎出現問題,所以無法順利下載,我把下載檔案的地址切到 NSF 在 Github 的 mirror。
NSF 釋出了 2.3.0,所以我更新了我自己的 openSUSE RPM spec, 這可以比較方便進行測試。我在下載的時候 SourceForge 似乎出現問題,所以無法順利下載,我把下載檔案的地址切到 NSF 在 Github 的 mirror。
2019-05-09
2019-04-16
使用 QEMU 執行 openSUSE/AARCH64 image
因為 tclBlend 我接到一個 issue,在 AARCH64 下編譯失敗,所以需要一個 AARCH64 模擬器來除錯。
首先要安裝 QEMU-ARM:
要下載一個 openSUSE AARCH64 image 來進行測試(我使用 unxz 解壓縮)。
如果使用 efi image,需要有 Unified EFI BIOS 模擬器正確的載入 boot loader 才行(不然無法正確執行)。我從 Linaro 下載一個來使用。
然後就可以這樣執行:
(使用者帳號為 root,密碼為 linux)
參考文章:
openSUSE:AArch64
Documentation/Platforms/ARM
Linux on AArch64 ARM 64-bit Architecture
Building ARM Servers With UEFI And ACPI
就 ARM 來說,有二種描述 hardware scheme 的方式,一種是 UEFI/ACPI,一種是 Device Tree。Linux kernel 可以編譯為二種都支援。文件中有提到:
ACPI support in drivers and subsystems for ARMv8 should never be mutually exclusive with DT support at compile time.
At boot time the kernel will only use one description method depending on parameters passed from the boot loader (including kernel bootargs).
Regardless of whether DT or ACPI is used, the kernel must always be capableof booting with either scheme (in kernels with both schemes enabled at compile time).
首先要安裝 QEMU-ARM:
sudo zypper install qemu-arm
要下載一個 openSUSE AARCH64 image 來進行測試(我使用 unxz 解壓縮)。
wget https://download.opensuse.org/ports/aarch64/factory/images/openSUSE-Tumbleweed-ARM-JeOS-efi.aarch64-Current.raw.xz
unxz openSUSE-Tumbleweed-ARM-JeOS-efi.aarch64-Current.raw.xz
如果使用 efi image,需要有 Unified EFI BIOS 模擬器正確的載入 boot loader 才行(不然無法正確執行)。我從 Linaro 下載一個來使用。
wget https://releases.linaro.org/components/kernel/uefi-linaro/16.02/release/qemu64/QEMU_EFI.img.gz
gzip -d QEMU_EFI.img.gz
然後就可以這樣執行:
qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.img -serial stdio -device virtio-net-device,netdev=hostnet0,id=net0,mac=52:54:00:09:a4:37 -netdev user,id=hostnet0 -drive if=none,format=raw,file=openSUSE-Tumbleweed-ARM-JeOS-efi.aarch64-Current.raw,id=hd0 -device virtio-blk-device,drive=hd0
(使用者帳號為 root,密碼為 linux)
參考文章:
openSUSE:AArch64
Documentation/Platforms/ARM
Linux on AArch64 ARM 64-bit Architecture
Building ARM Servers With UEFI And ACPI
就 ARM 來說,有二種描述 hardware scheme 的方式,一種是 UEFI/ACPI,一種是 Device Tree。Linux kernel 可以編譯為二種都支援。文件中有提到:
ACPI support in drivers and subsystems for ARMv8 should never be mutually exclusive with DT support at compile time.
At boot time the kernel will only use one description method depending on parameters passed from the boot loader (including kernel bootargs).
Regardless of whether DT or ACPI is used, the kernel must always be capableof booting with either scheme (in kernels with both schemes enabled at compile time).
2019-04-10
Difference between 2 dates in XQuery
package require xqilla
xqilla db
set exprs [db prepare {days-from-duration(xs:dateTime('2019-06-14T00:00:00') - current-dateTime())}]
set result [$exprs execute]
set diff 0
while {[$result next]} {
set diff [$result string_value]
}
puts "The answer is $diff."
$result close
$exprs close
db close
使用 XQuery 的日期函式計算出二個日期間的差距,這裡使用 XQilla 測試。
Difference between 2 dates in SQLite3
package require tdbc::sqlite3
tdbc::sqlite3::connection create db :memory:
set statement [db prepare {SELECT CAST ((JulianDay('2019-06-14') - JulianDay('now')) as Integer) as d}]
set diff 0
$statement foreach row {
if {[catch {set diff [dict get $row d]}]} {
set diff 0
}
}
puts "The answer is $diff."
$statement close
db close
使用 SQLite3 的日期函式計算出二個日期間的差距,這裡使用 tdbc::sqlite3 測試。
2019-03-04
tkimg 1.4.9
tkImg
tkImg 釋出了一個新的版本,1.4.9。
下面是節錄的說明:
This file contains a collection of format handlers for the Tk photo image type, and a new image type, pixmaps. It can be used in combination with Tcl/Tk 8.3 or later but 8.6 or newer are highly recommended.
Included in this distribution are the most recent versions (as of March 2019) of the libz, libpng, libjpeg, and libtiff libraries. These are not required, unless you need support for the PNG, JPEG, or TIFF format. Note that you have to build these libraries to support the named formats, even if your system already has shared libraries for these formats. This is because the libraries here are built such that they can be loaded as packages by the Tcl/Tk core, making the handling of the various dependencies much easier. An earlier version, 1.2.4, used a modified copy of Tcl's functions for loading of shared libraries to load the support libraries at runtime. These have been abandoned in favor of the new approach.
tkImg 釋出了一個新的版本,1.4.9。
下面是節錄的說明:
This file contains a collection of format handlers for the Tk photo image type, and a new image type, pixmaps. It can be used in combination with Tcl/Tk 8.3 or later but 8.6 or newer are highly recommended.
Included in this distribution are the most recent versions (as of March 2019) of the libz, libpng, libjpeg, and libtiff libraries. These are not required, unless you need support for the PNG, JPEG, or TIFF format. Note that you have to build these libraries to support the named formats, even if your system already has shared libraries for these formats. This is because the libraries here are built such that they can be loaded as packages by the Tcl/Tk core, making the handling of the various dependencies much easier. An earlier version, 1.2.4, used a modified copy of Tcl's functions for loading of shared libraries to load the support libraries at runtime. These have been abandoned in favor of the new approach.
2019-02-14
Update tcl-cmark
2019-02-11
2019-01-23
otpcl
otpcl - Open Telecom Platform Command Language a.k.a. Tcl-Flavored Erlang
這是一個很有趣的案子,在 Erlang VM 寫一個類似 Tcl 的語言,但是目前只是在極早期開發的階段,看起來是有一些東西可以用但是離真的能實際使用仍然有一大段的距離。
Erlang 最近幾年似乎聲勢有掉下來的情況(我是指本來就有點小眾的情況變成真的小眾,然而 WhatsApp 又再次證明 Erlang 在網路程式上真的有其優越之處),但是分散式系統或者是 concurrent solution (也就是 Actor model) 方面仍然是眾多解決方案「致敬」的對象。
這是一個很有趣的案子,在 Erlang VM 寫一個類似 Tcl 的語言,但是目前只是在極早期開發的階段,看起來是有一些東西可以用但是離真的能實際使用仍然有一大段的距離。
Erlang 最近幾年似乎聲勢有掉下來的情況(我是指本來就有點小眾的情況變成真的小眾,然而 WhatsApp 又再次證明 Erlang 在網路程式上真的有其優越之處),但是分散式系統或者是 concurrent solution (也就是 Actor model) 方面仍然是眾多解決方案「致敬」的對象。
2019-01-01
promise 1.1.0
ANNOUNCE: promise 1.1.0 released
tcl-promise-spec
Promises are concurrency primitives that let you write asynchronous code in a sequential style. This Tcl based implementation is mostly modeled on the Javascript/ECMAScript 7 standard.
因為作者釋出新版,所以我也更新了我自己的 openSUSE RPM spec.
tcl-promise-spec
Promises are concurrency primitives that let you write asynchronous code in a sequential style. This Tcl based implementation is mostly modeled on the Javascript/ECMAScript 7 standard.
因為作者釋出新版,所以我也更新了我自己的 openSUSE RPM spec.
訂閱:
文章 (Atom)