碧落にて気まぐれに一言

2011/09/18

AiB ToolsのためにMercurialを導入してみました

Filed under: 未分類 — タグ: , — Suguru Yamamoto @ 22:22

AiB Toolsのソース管理のために、分散バージョン管理システムMercurialを使ってみることにしました。AiB ToolsはライセンスもMITですしソースを公開していますからオープンソースと言えばオープンソースです。が、SorceForgeやCodePlexなどといったサービスを利用していません。というのも、ユーザ層は日本の重度視覚障害者なので、スクリーンリーダ等でアクセスしやすい上に日本語で使用できるサービスでないとダメだと思っています。残念ながら、そのようなサービスが今のところ見つからないので、ローカルで開発しているわけです。

さて、で、先日VAIO Zを購入したので2台で作業を共有する必要が出てきました。今まではローカルファイルシステムにレポジトリを作ってSubversionで管理していたのですが、2台ともにその構成を取ると非常に不都合です。両方にレポジトリを置いた場合は同期が面倒ですし(思いつく方法はどちらかでsvnserveを起動してsvn syncをかける…)、かといってどちらか一方をマスターにしてしまうと2台に作業環境を用意している意味が無くなります。というわけで、マスターという概念がシステム的に存在しないDVCSを使おうと思いつき、gitとMercurialを比べて、用語が自分により自然な印象を受けるMercurialを採用してみました。もう一つの理由はTortoiseGitとTortoiseHgの比較結果ですが。とりあえず本日修正の機会があったので少し使ってみましたが、同期は次のような手順で行えました。

  1. デスクトップPCのレポジトリを右クリックしてWeb Serverを起動
  2. ノートPCからデスクトップPCのIPアドレスとポート番号を指定してpush
  3. デスクトップPC側でpush結果をmerge

使い始めたばかりなので用語が違うかもしれませんが、ご容赦ください。うーん、思ったより楽でも無いですが、Subversionで同じことをするよりはマシですね。

ただ一つ思ったのは、DVCSが出てきた頃によく話に上がった作業形態の違いよりも、Subversionで言うところのワークスペース・ローカルコピー自体がレポジトリになるという点が一番知っておきたかったです。Subversionのつもりで空フォルダをhg initしてcheckoutしようとしてしまいました。trunk/branches/tagsという管理用フォルダ分け、という考え方も、ありませんしね。それを知らなかったためSubversionのレポジトリのルートをhg convertしてしまい、一からやり直しになりました(Subversionレポジトリのtrunkを指定してhg convertするとタグやブランチもMercurial的に望ましい形で取り込んでくれる)。

2011/07/30

Java 7とラムダ式

Filed under: 未分類 — タグ: — Suguru Yamamoto @ 15:35

Java 7がリリースされたようですね。ラムダ式が先送りになったので、個人的に興味を持つようなエンハンス内容は今回は無いですね…むしろJava FX 2.0のリリースが気になる。

以下、すべて個人的な意見というか見解です。Javaはオブジェクト指向原理主義だったため、本来はオブジェクト指向でない方法が適している場面でも、他の流儀を取り入れずオブジェクト指向的に実現してきたと思います。具体例は、コレクションの中から特定条件を満たすような要素を検索する、コレクションを特定の条件に従ってソートする、GUIやタイマーなどによって発生するイベントが発生した直後に実行したい処理をGUIやタイマーに指示する、といった場面です。これらはみな、「処理を変数として扱う」ことができれば何も苦労はありません。こうした場面では、いわゆる関数ポインタ(C)、述語オブジェクト(C++)、匿名メソッド(Lisp, JavaScript, C#)、クロージャ(色々な言語)といった言語機能を使うとスッキリ実現できるのですが、Javaではこのような場面でComparatorインタフェースやKeyListenerインタフェースを実装したクラスのオブジェクトを用意する必要があります。このあたりが非常に面倒だと感じているわけなのですが、ラムダ式が正式導入され、各種コレクションやGUIクラスにラムダ式をパラメータとして受けるオーバーロードなどが実装されれば、非常に世界は明るくなります。できれば複数行を記載できるクロージャになるともっと良いと思いますが。

具体的に、もしArrayListにラムダ式を引数に取るindexOfのオーバーロードやsortメソッドなどが追加された場合、おそらく次のようなコードが書けると思っています。

ArrayList<int> numbers = getSomeNumbers();

// 最初の奇数を検索
numbers.indexOf( #{int n -> ((n%2) != 0)} );

// 昇順にソート。ただし4だけは特別扱いして常に最初に来るようにする
numbers.sort( #{int x, int y ->
        if(x == 4) {
            return -1;
        } else if(y == 4) {
            return 1;
        }
        return (x - y);
    });

うーん、ラムダ式はとりあえず見送りという話ですが、クロージャはどうなんだろう(クロージャが導入される場合、ラムダ式はクロージャの一機能・一形態という話になると思います)?ま、いずれにせよJava 8以降ですから、当分先ということで忘れるとします :)

2011/04/24

VirtualBoxでシリアルポート(COMポート)を使う

Filed under: 未分類 — タグ: , , — Suguru Yamamoto @ 14:13

マシン仮想化ソフトであるOracleのVirtualBoxで、シリアルポート(COMポート)を使う場合の設定方法についてメモします。使えることは昔から分かっていたのですが、設定方法などを調べることができていなかったので本日実施。備忘録です。なお、使用したVirtualBoxのバージョンは4.0.4です。

最初に設定画面のスクリーンショットを掲載しておきます。
VirtualBoxでのシリアルポートの設定画面例
さて、おそらくゲストOS(仮想マシン)がホストOS(物理マシン)のシリアルポートを直接使いたい、というケースが一番多いのではないかと思いますが、ここではあえて一般的に説明してみます。VirtualBoxのゲストOSの設定画面を開いたら「Serial Port」を選択し、各設定項目を次の通り設定します。なお設定画面のタブは「Port 1」でも「Port 2」でも構いません。2つの仮想シリアルポートをゲストOSで使いたい場合は、両方のタブを設定すればOKです。

  • Enable Serial Port: 該当画面の設定を有効にする=仮想シリアルポートをゲストに見せる場合はチェックします
  • Port Number: ゲストOSからこの仮想シリアルポートが何番目のシリアルポートに見えるかを設定
  • IRQ: (普通は標準通りで良いです)
  • I/O Port: (普通は標準通りで良いです)
  • Port Mode: (後述します)
  • Port/File Path: (Port Modeの指定によって意味が変わります)

Enable Serial Port、Port Numberは説明不要だと思います。IRQとI/O Portについては、これらの値が決まらないと「OSがシリアルポートを使えない」ことだけ理解すれば問題ありません。Port ModeとPort/File Pathは、Port Modeの選択肢ごとに次のような意味になります。

  1. Disconnected: 何も接続されていないシリアルポートがあるように見せかける方法です。シリアルポートを列挙するプログラムをゲストOSで開発・検証する場合など、とりあえずダミーであってもポートが存在していて欲しい場合に使います。Port/File Pathの値は無視されます。
  2. Host Pipe: ホストOS上の名前付きパイプをシリアルポートに見せかける方法。高度な使い方ですので普通は使いません。ホストOS上で動いているプログラムとリアルタイムで通信したい場合で、しかもTCP/IPなどの通信が使えないような場合などに使います(おそらくこの設定を使うのはOS自体を開発する場合ぐらいではないかと思います)。Port/File Pathの値には名前付きパイプの名称を指定します(Windowsならば\\.\pipe\mypipenameなど)。
  3. Host Device: ホストOS上で使えるシリアルポート(=物理マシンの物理的なシリアルポート)をそのまま使わせる方法。まさに「そのまんま」な方法ですが、ポート番号、IRQ、I/O Portアドレスといったパラメータを変更することもできます。Port/File Pathの値には、COM1を使う場合は「COM1」、COM2を使う場合は「COM2」などと指定します。
  4. Raw File: ホストOS上のファイルをシリアルポートに見せかける方法。使ったことがないため憶測ですが、指定したファイルにホストOS上で何かを書き込むとその内容がゲストOSに送信され、ゲストOS側でシリアルポートに何かを書き込むとその内容が指定したファイルに書き込まれる、という形になると思われます。Port/File Pathの値には、このような用途で使いたいファイルのパスを指定します。

ホスト側の設定は以上です。ゲストOS側については、おそらく正しく設定した状態でOSをインストールすれば認識されるはずだと思います。もし後から追加する場合、ゲストOSの側でシリアルポートの設定を追加してください(たとえばWindows 2000ではコントロールパネルから「ハードウェアの追加と削除」を選択し、「デバイスの追加/トラブルシューティング」、「新しいデバイスの追加」、「いいえ、一覧からハードウェアを選択します」、「ポート(COMとLPT)」、「製造元=(標準ポート)、モデル=通信ポート」と選択して、IRQをVirtualBoxのIRQの設定値に合わせ、I/O範囲の開始アドレスをVirtualBoxのI/O Portの設定値に合わせます)。Windows 2000で設定した画面例を次になります。
Windows 2000でのシリアルポートのプロパティ画面
なお、VirtualBox側でCOM1として見えるよう設定した場合でもゲストOS側でCOM1と認識されるとは限りません。このあたりの理由はまだ分からないのですが、実用上は問題ありませんので「そういうものだ」と理解しています。

シリアル通信の開発を経験されている方の中にはHost DeviceモードでCOM1を指定する場合とRaw FileモードでCOM1を指定する場合にどう違うのか疑問に思われる方もいらっしゃるかと思います。詳細は未確認ですが私としては、Raw Fileモードでホストからデータを送信する場合はVirtualBoxが定期的に指定ファイルの更新日付を監視し、更新を検出するたびにゲストOSへ送信することになる(つまりリアルタイム通信にならない)と想像しています。実際にRaw Fileモードで\\.\COM1など指定して通信してみたところ通信速度が猛烈に遅くなりましたので、物理シリアルポートを使う場合はHost Deviceモードを選択した方が良いことは間違い無いようです。

2011/04/17

「一太郎2011 創」の初使用

Filed under: 未分類 — タグ: , , — Suguru Yamamoto @ 22:47

本日「.NETでドラッグ&ドロップ」という記事を公開しました。

この記事には名前の通り.NET上でドラッグ&ドロップを実装する場合の話を書いてあるのですが、合計4種類のGUIフレームワークを比較しつつドラッグ&ドロップAPIの考え方や使い方を記してあります。まあ、どちらかというと説明というより自分用のメモ書きを、他人でも読めるように整えたものですので不親切な部分も多々あるかもしれません。

私にとっての本記事、もう一つの価値は「一太郎2011 創」を初めて使って書いたことです。モリサワのフォントを使えるということで、一つぐらいは技術記事を新しく書いてPDF形式で公開したかったのです ;)

そんな不純(?)な動機もあって、今回はPDF版が用意されています。PDF版では、モリサワフォントの美しさもお楽しみください :)

(暇があったらヒラギノフォント版も作ってみたいなぁ…)

2011/03/13

正規表現の「^」記号とマッチング範囲

Filed under: 未分類 — タグ: , , — Suguru Yamamoto @ 20:06

はじめに

(2011/4/6追記。本件はMicrosoftから将来のリリースで修正するとの回答がありました)
(2011/8/27追記。最新版のVisual Studio 2010+最新の.NET Framework 4で試したところ、まだ修正されていないようです。)

本日、各言語での正規表現エンジンを使って「^」記号(文字列または行の先頭を示す、アンカーあるいはゼロ幅アサーション…と呼ぶらしい)に関する動作を調査しました。背景にあるのはAzukiが内蔵している正規表現検索で行頭マッチングが行われないというユーザ報告の不具合(に近いが対策できず黙認していた動作仕様)です。過去に検索機能を実装した際の調査結果では.NETの正規表現エンジンで「Multilineモード」を有効にしても各行の先頭でない位置でマッチする現象が起こり、使えないと判断しました。今回は、この問題を改めて少し掘り下げて調査した結果報告(?)となります。

調査結果のポイントです。

  1. Microsoftの.NETが提供する正規表現エンジンでは、マッチング範囲の終了位置を指定すると「^」が常に「マッチング範囲の開始点」にマッチしてしまう(終了位置を指定しなければ常にはマッチしない)
  2. MSDNの「^」記号の説明Regex.Matchメソッドの説明からは「^」が文字列の先頭でも行頭でもない箇所にマッチする動作は予想しにくい上に、Regex.Matchのオーバーロード間での動作仕様の統一性が失われている
  3. Java (1.5以降)の正規表現エンジンでは「Anchoring Bounds」という概念で「^」の扱いをカスタマイズできる(→ Matcherクラスのリファレンス)が、.NETでは同等の機構が無い
  4. ユーザ指定の正規表現を使うアプリケーションで、特定のマッチング範囲を絞り、「^」をマッチング範囲の開始点にマッチさせたくない場合、実現できないと思われる

ポイント1および2です。Regex.Match(string,int)のオーバーロードを使ってマッチング開始点だけを指定した場合には、行頭でも文字列先頭でもない位置がマッチング範囲の開始点であっても「^」記号は該当位置にマッチしません。しかしRegex.Match(string,int,int)のオーバーロードを使うと、マッチします。したがってオーバーロード引数を追加するだけで動作仕様が変化してしまうため、不自然な印象を受けます。次に例を記します。

string text = "abc";
new Regex( "^[a-z]" ).Match( text, 1 ); // どこにもマッチしない
new Regex( "^[a-z]" ).Match( text, 1, text.Length ); // 1文字目のbでマッチする

ポイント3です。Javaの正規表現エンジンでは「Anchoring Bounds」という概念があり、「^」記号の扱いをカスタマイズできます。Anchoring Boundsを使うよう設定すると、「^」記号および「$」記号のマッチング時にマッチング範囲の前後が考慮されない — つまり問答無用でマッチング範囲の始点に「^」記号がマッチするようになります。そしてAnchoring Boundsを使わないよう設定すると、マッチング範囲の開始点が文字列先頭あるいは行頭でない限り、「^」記号はマッチング範囲の開始点にマッチしません。このように「^」記号のマッチング動作を明示的に指定できる機構があれば、それを使うことで問題回避できますが、残念ながら.NETにはありません。

ポイント4です。どうやら.NETの正規表現エンジンではJavaでいう「Anchoring Bounds」の扱いがRegex.Matchのオーバーロードごとに異なっており、Regex.Match(string,int)はAnchoring Boundsを使わず、Regex.Match(string,int,int)はAnchoring Boundsを使う動作となっています。ここで、もしAnchoring Boundsを「常に使いたい」場合は外部でマッチング対象の文字列をSubstringすることで代替できます。しかしAnchoring Boundsを「常に使いたくない」場合、Regexクラスの外部でこれを実現する方法は無いように思われます。

この仕様はAPIからもドキュメントの記述内容からも想定できるものでなく、また統一が取れていないという点も考えると、意図的な設計結果とは思えません。本件は、改めてMicrosoft社に報告と確認をしておこうと考えています。

以下、各言語・環境での検証コードおよび検証結果を記します。なお言うべきことはすでに記したので、細かい説明はしません。興味のある方や再現してみたい気分になった方へ向けた情報です。

(続きを読む…)

2011/02/16

丸投げ

Filed under: 未分類 — タグ: , — Suguru Yamamoto @ 22:10

ソフトウェアは設計上の階層構造を持つことが多く、ほぼ間違いなく最上位をアプリ層(そのアプリ固有の処理)とした複数の階層を重ねた形になっています。ごく単純なアプリの場合は最上位のアプリ層のみが存在すると解釈すれば、やはり階層構造です。このとき、特に最初が単純な一階層のアプリだったものに機能を追加していく場合、ある程度の規模を越えると階層構造を組まないと管理不可能になっていきます。本日はこの階層構造と「丸投げ」について思うことを書きます。
(続きを読む…)

2010/09/11

AiB Toolsの悲願が達成

Filed under: 未分類 — タグ: , , — Suguru Yamamoto @ 14:06

本日、AiB Tools 3.1を公開しました。

ついに、本バージョンからニュー・ブレイル・システム株式会社のピンディスプレイ点字出力エンジン「ピンブレイル」を無償でインストーラに同梱できるようになりました。これで、インストールしたら即、音声でも点字でも操作可能な環境が構築されます。最初に公開したときからの悲願が達成、です。

AiB Toolsは2005年、大学生だった頃に作り始めてから現在に至っており、すでに5年間の付き合いになっています。生活時間の位置づけ上は「趣味」になってしまうAiB ToolsとAzukiには、なかなか時間を使えず話が進みません。ですが、活発でなくともプロジェクトを死なせず生き続けさせることにも価値はあると思っています。

最近は平日の時間は体調の問題があって使えず、週末も用事が入って使えない、などということがあります。自分一人のことだけ考えてはいられなくなる。ことが大人になるということなのでしょうかね。ああっと、まあ体調の話はまったく無関係ですが ;)

2010/09/04

7-Zipの自己解凍ファイルを簡易インストーラにする

Filed under: 未分類 — タグ: — Suguru Yamamoto @ 23:32

7-Zipの自己解凍ファイルを簡易インストーラ化する方法についての備忘録です。

  1. 普通に.7zファイルを作成
  2. 7-ZipのウェブサイトからExtraパッケージをダウンロード
  3. Installerフォルダ内にあるreadme.txtを読みながらconfig.txtを調整
  4. Installerフォルダ内にあるcr.batで.7zファイルと自己解凍処理部を結合

本質的には圧縮解凍ソフトの機能ではないので、7-Zip FMのGUIで作成できないのは仕方ないとは思いますが、ふーむ、手間がかかることよりも手順を忘れてしまいそうな感覚があって嫌な感じです。お手軽ツールがあれば忘れる心配が無用になるので良いのですが、まあそれはまた今度調べるとします…今は時間が無い。

2010/08/08

Windows Phone Developer Tools(β版)を試してみました

Filed under: 未分類 — タグ: , — Suguru Yamamoto @ 18:06

Windows Phone Developer Toolsのベータ版を試してみました。一番の目的は、Windows Phone 7がどんな感覚のOSになるのかをエミュレータで知った気分になることです :)

まずはWindows Phone Developer Toolsをダウンロードし、インストールしました。Windows Phone 7アプリを作るのに必要なツール類(Visual Studio 2010 Express for Windows Phone、Expression Blend for Windows Phoneなど)も同梱されており、インストール後にVisual Studio 2010 Express for Windows Phoneを起動すると初期画面にチュートリアルのウェブページへのリンクなどが表示されます。とりあえず、そのチュートリアルに従ってSilverlight for Windows Phoneのお試しアプリを作ってみたところ、非常に簡単に作成できました。なお作成したアプリだけでなくエミュレータでOS自体の使用感を確認しましたが、個人的には良い印象です。ただ開発用のエミュレータだからか、IEぐらいしかアプリが無く、電話帳などもありません。電話機としての使用感や「ハブ」というモノの使用感を試してみたい!と期待していた私的には少し残念でした…もちろん勝手に期待する方が悪いのですが ;)

さて開発の話です。Windows Phone 7用アプリは基本的に二種類に分類されます。Silverlightアプリか、XNAアプリです。後者はゲーム用フレームワークなので、ゲーム向けです。その他のアプリについてはSilverlightで作るのが基本となります。Windows Phone 7向けのSilverlightはVersion 3をベースに専用の機能を加えたものらしいですね。ということは、Silverlight 4の新機能であるクリップボードアクセスとローカルファイルアクセスは使えないということでしょうかね。まあ、特に前者はずいぶん前から言われていたことなので驚くことも無いですが。

ところで、今頃になって知ったのですがMSDNには次の記述があります。

WPF での表示はすべて DirectX エンジンによって実行されるようになっています。

なるほどWPFのサブセットで描画しているSilverlightがあれだけなめらかなアニメーションを表示できているのは、やっぱりハードウェアアクセラレーションが効いているからなのですね。そしてGDIではなくDirect X。納得です。コンピュータ画面は96 dpiしか無いと考えて良かった昔はピクセルを描画基準にしているGDIで何も不自由ありませんでしたが、高いDPIを持つデバイスが増えている今、描画単位がピクセルでは正直厳しいと思っていました。急速に、GDIは過去の遺物になりつつあると感じてしまいますね。まあピクセルが描画単位になっている上に事実上ハードウェアアクセラレーションが効かないGDI+に比べれば、GDIは素晴らしいモノですが。

…まったく、AzukiでGDI+ (System.Drawing.Graphics) を使わなくて本当に良かった… :|

2010/08/01

jayはCで書かれている

Filed under: 未分類 — タグ: — Suguru Yamamoto @ 23:16

jayというパーサジェネレータがあります。今日までずっと、これはJavaで書かれたものだと思い込んでいました。が、Cで書かれているんですね。この思い込みのせいで時間を無駄してしまいました…。

以前調べたときには「yaccのJava版です」とか「yaccをJavaに移植したものです」などという解説をよく見かけたのです。この表現を読んでてっきりJavaで書かれていると思んだ当時の私は、jarファイルだけダウンロードして保管しておきました。そして、今日使ってみようと思ってjarを取り出して使ってみたところ全然まともに動作しません。具体的には、文法定義ファイルを正しいコマンドラインでフルパスで指定しているのにファイルを開けないとエラーが出てしまいました。仕方がないのでソースをダウンロードしてファイルオープンに失敗する原因を調べようと思ったところ、ソースがCで書かれていて驚いた、という経緯です。

いや、改めて調べてみると、古いオフィシャルサイトに堂々とCで書かれていると書かれているのですが…新しいオフィシャルサイト(?)にはjarファイルでの配布が行われています。うーん、いったいなんでjarファイルで配布しているんでしょう??しかもjarを開くと.classファイル群が入っていて確かにJavaプログラムのような感じなのですが…はて。

まあ、CのソースはVisual Studio 2008で普通にビルドできましたので、深追いするより自前ビルドしたexeを使うことにします :)

Older Posts »

Powered by WordPress