0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Tcl 9.0の「重要な非互換性」にハマった話 (Tcl 9.0でTcllib ftpdを使う方法)

Posted at

ひょんな事からTcl 8.6と9.0の些細(?)な違いにハマりました。

Tcllibのftpdを使おうとしたところ、Tcl 8.6ではpackage requireに成功するのに、Tcl 9.0ではエラーになりました。

Tcl 8.6
% package require ftpd
1.4.1
Tcl 9.0
% package require ftpd
can't read "tcl_platform(user)": no such variable

実行環境はMagicsplatからダウンロードした以下のインストーラで導入したものですが、

  • Tcl 8.6: tcl-8.6.16-installer-1.16.1-x64.msi
  • Tcl 9.0: tcl-9.0.2-installer-2.0.4-x64.msi

どちらに入っているtcllib ftpdも1.4.1で同じファイルでした。

9.0でエラーにっている箇所はftpd.tclの冒頭の

ftpd.tcl
namespace eval ::ftpd {
    :
    variable contact
    if {![info exists contact]} {
        global tcl_platform
        set contact "$tcl_platform(user)@[info hostname]"
    }
    :

という部分なのですが、Tcl 8.6ではglobalが効いているのに、Tcl 9.0では効いていない事がわかりました。

Tcl 8.6でも9.0でもglobalのヘルプには

This command has no effect unless executed in the context of a proc body.

と書かれていますが、Tcl 8.6ではヘルプに反してnamespace evalでもglobalが効いてしまっていたのが、Tcl 9.0ではバグフィックスされちゃったということですね。

Tcl 9.0のリリースノートを確認すると、ちゃんと載ってました。でもこれ見ただけで影響範囲を理解するのは難しい気がします。

Important Incompatibilities in Tcl 9.0
・Namespace varname resolution: Current namespace, not global.
:
Notable incompatibilities
・Unqualified varnames resolved in current namespace, not global. Note that in almost all cases where this causes a change, the change is actually the removal of a latent bug

重要な非互換性とは認めつつも「ちゃんとヘルプ読んで使ってりゃ問題ないやろがぃ」とか言われてるみたいで、いい気はしないですね。実際、ヘルプと実挙動が違ったら、「ヘルプの更新が遅れてるのかな?」と思う方が一般的じゃないでしょうか。

一応、tcllibの開発元に指摘をしておきましたが、そっちのバグフィックスを待たずにTcl 9.0でftpdを使いたい場合は、以下のようにすればOKです。

Tcl 9.0
% namespace eval ::ftpd {variable contact;set contact "$::tcl_platform(user)@[info hostname]"}
% package require ftpd
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?