|
バージョン8.6の新機能を、面白そうな順に試してみたいと思います。これらの情報源としては、 Changes in Tcl/Tk 8.6と、 A Busy Developer's Guide to Tcl/Tk 8.6がとても参考になります。 またマニュアルはhttp://www.tcl.tk/man/tcl8.6/です。
Zlibは、 Jean-loup Gailly さんと Mark Adler さんによって開発された、 オープンソースのデータ圧縮・展開ライブラリです。 このライブラリを使った処理がTcl処理系の標準に取り込まれました。 zlibコマンドには、3系統の圧縮・展開コマンドの対があります。 gzipとgunzip、compressとdecompress(注:uncompressではありませんよ)、 そしてdeflateとinflate(注:deflateの方が圧縮です。inflateの方が展開です。 何となく語感上、deがつかない方が圧縮のように聞こえますが反対なので要注意!)です。
また、zlib gzipで圧縮したデータはgzipコマンドと互換性があります。 また上の例のようにファイルからバイナリモードで明示的に読んでいる場合はいいのですが、 Tcl文字列をそのままzlibコマンドに渡して圧縮することはできません。 encoding converttoコマンドでバイナリに変換してから圧縮し、 展開後もencoding convertfromコマンドで復元する必要があります。
また、zlib gunzipコマンドでは、gzipヘッダ部分を読み取って、dict変数に格納することができます。 (ここでは触れませんが、逆にzlib gzipコマンドの-headerオプションでgzipヘッダを埋め込むことも可能です)
世界中の有志の皆さんによって、Tclには各種のRDBMS (リレーショナルデータベース管理システム)へ接続するための拡張ライブラリが提供されています。 一例をあげると、OracleにはOratcl、 MySQLにはmysqltcl、PostgreSQLにはlibpgtcl、 SQLiteにはtclsqliteなどなどです。 しかし残念ながら、それらの拡張間でコマンドや名前空間の名前などに統一した仕様がないため、 複数のRDBMS製品を扱うTcl開発者は、 各拡張のコマンド作法などをそれぞれマニュアルを見て覚える必要がありました。 同様の問題は他のプログラミング言語にもあって、 企業情報システムで利用されることをかなり早期から想定していたJavaは、 いち早くJDBCというAPI仕様をSun自らが整備しました。 Python、Perlも、それにならってAPI仕様が既に整備されました。 遅まきながら、Tclも同様の方針となったことは大変嬉しいことです。 それでTcl 8.6には、TDBCというパッケージと、 参照実装としていくつかのRDBMS向けの実装が提供されています。 ODBC、SQLite、MySQL、PostgreSQL、そしてOracleです。 ただし私がActiveTcl 8.6.0をインストールして試したところ、 「package require tdbc::sqlite3」で 「unknown method: -columns」というエラーになって駄目でした。 そこで、Windows環境では tdbc.tcl.tk で最新のソース配布を入手して、 MinGWなどでコンパイルする必要があります。 私はActiveTcl 8.6.0、MinGW 5.1.6を使って TDBCソース配布1.0b17をコンパイルし、 Sqlite3とODBCの動作確認ができたのでその手順をご紹介します。 MySQL、PostgreSQL、Oracleは試していません。
一応、ODBCに接続する例です。
なお、 http://www.tcl.tk/man/tcl8.6/TdbcCmd/contents.htm に、tdbcパッケージのコマンドのマニュアルがあります。
えっ?オブジェクト指向が「面白そうな順」でTDBCより下なのはおかしいだろうって。 そんなことありませんばい!(どこの人じゃ) 過去長きに渡って議論されては見送られてきたオブジェクト指向 (OO:Object Oriented) プログラミングの機構が、8.6でやっとTcl世界にも訪れました。 従来代表的なOO拡張であった[incr Tcl]とはかなり文法が違いますが、 Java、Python、PHP5などに慣れていれば、 大体の感じはすぐにつかめるように工夫されていると思います。 例として、メソッドを呼ぶたびに回数を記録し、 その回数を返すことができる「アクセスカウンタ」風のクラスを作ってみます。
コンストラクタはconstructorで定義します。 同じようにデストラクタは destructorで定義します。 この例では引数がありませんが、引数を持つコンストラクタも作れます。 インスタンスメソッドは methodコマンドで定義します。 それらの中で、インスタンス変数を参照することを my variableで定義します。 インスタンス化は [クラス名 new]で行います。 それで上の例で気になるのは、 各メソッド内でインスタンス変数の参照を逐一 my variableで定義しないといけないのは面倒そう、 というところですね。これは、改善可能です。 その点も含めて、少し拡張した例を次に示します。
そして上の例ではもうひとつ、メソッドのpublic/privateの切り替え方法を示しています。 デフォルトでは、 インスタンスメソッドの名前が英小文字で始まる場合はpublic、 それ以外ならprivateとして扱われます。 つまり上の例では、_getCountはprivateなので、外部から[$c _getCount] として呼ぶことはできずエラーになります。 また oo::defineのexport、unexport コマンドを使うことで、個別のインスタンスメソッドに対して、 public/privateを明示的に指定することもできます。
「image create photo」コマンドなどでロードできる画像フォーマットとして、 従来のTcl/Tkは標準でPPM/PGMとGIF形式のみをサポートしており、 その他の画像フォーマットはImg拡張などの拡張を使う必要がありました。 今般、バージョン8.6でzlibのサポートと合わせてか、 zlibと縁の深いPNG(Portable Network Graphics) 形式が使えるようになりました。 使い方はGIF等の場合と全く同じです。
lmapというコマンドが追加されました。 リストに対するフィルターのような処理を、foreachループよりも少し簡潔に書けます。 以下の例は、$dirfile ディレクトリにあるファイルの内、 絶対パスが "処理済.txt" に書かれていないファイルだけを選び、 ファイル名順にソートして配列に取得する処理です。 なお::fileutil::catはStandard Tcl Library(tcllib) に含まれるコマンドで、ファイルの内容を丸ごと取得するコマンドです。
|