関数は「どう呼ばれうるのか」も考えて仕様を設計すると良い
問題。文字列の指定位置にあるマルチバイト文字が何バイトで構成されているか判定する関数を考える。その関数の引数として、与える文字列の長さに等しい値を、判定すべき文字の位置(インデックス)として指定した場合、この関数仕様は以下いずれが望ましいか。
- 成功とし、0バイトと判定する
- 例外(対象が見つからない)とする
- 例外(引数不正)とする
問題。文字列の指定位置にあるマルチバイト文字が何バイトで構成されているか判定する関数を考える。その関数の引数として、与える文字列の長さに等しい値を、判定すべき文字の位置(インデックス)として指定した場合、この関数仕様は以下いずれが望ましいか。
昔のメモを見つけたので投稿しておきます。 手続き的なプログラミング言語ではループをよく書くと思いますが、大半は定型パターンがあります。たとえば配列のようなものから特定の条件を満たすものを検索する場合、普通は配列の要素を列 … 続きを読む コーディングパターン: ループ条件の定石を覆して良いことも
電子書類の整理をしていたところ古い読書メモが出てきました。何かの縁ということで、掲載。2009-05-17 16:29 A.D.ノーマン著「エモーショナルデザイン」より: ペンをカスタマイズする人はいない。ペンの使い方を … 続きを読む 「ペンをカスタマイズする人はいない。ペンの使い方をカスタマイズするのだ」
本日Azukiの不具合修正版1.6.2をリリースしました。一応当日のブログなので一言触れておきます 🙂 ここのところ悩んでいるのは3/13にも本ブログで記した「行ごとの編集状態」です。もともと想定していた範囲を超える仕様 … 続きを読む 行ごとの編集状態、その2
(2011/4/6追記。本件はMicrosoftから将来のリリースで修正するとの回答がありました)
(2011/8/27追記。最新版のVisual Studio 2010+最新の.NET Framework 4で試したところ、まだ修正されていないようです。)
本日、各言語での正規表現エンジンを使って「^」記号(文字列または行の先頭を示す、アンカーあるいはゼロ幅アサーション…と呼ぶらしい)に関する動作を調査しました。背景にあるのはAzukiが内蔵している正規表現検索で行頭マッチングが行われないというユーザ報告の不具合(に近いが対策できず黙認していた動作仕様)です。過去に検索機能を実装した際の調査結果では.NETの正規表現エンジンで「Multilineモード」を有効にしても各行の先頭でない位置でマッチする現象が起こり、使えないと判断しました。今回は、この問題を改めて少し掘り下げて調査した結果報告(?)となります。
調査結果のポイントです。
ポイント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社に報告と確認をしておこうと考えています。
以下、各言語・環境での検証コードおよび検証結果を記します。なお言うべきことはすでに記したので、細かい説明はしません。興味のある方や再現してみたい気分になった方へ向けた情報です。
Azukiでは行ごとに3種類の編集状態を定義し、管理しています。具体的には未編集、編集済み、保存済み(一度以上編集されたが最後に保存された状態から変化していない)の3状態です。Azukiで3状態を扱うようにした背景は安直 … 続きを読む 行ごとの編集状態
ソフトウェアは設計上の階層構造を持つことが多く、ほぼ間違いなく最上位をアプリ層(そのアプリ固有の処理)とした複数の階層を重ねた形になっています。ごく単純なアプリの場合は最上位のアプリ層のみが存在すると解釈すれば、やはり階層構造です。このとき、特に最初が単純な一階層のアプリだったものに機能を追加していく場合、ある程度の規模を越えると階層構造を組まないと管理不可能になっていきます。本日はこの階層構造と「丸投げ」について思うことを書きます。
続きを読む “丸投げ”
D.A.ノーマン先生の「未来のモノのデザイン」を読み終えました。実は発売直後に購入していたので読み始めはずいぶん前なのですが、読書時間をうまく取ることができておらず、今頃読み終わりました。これからは読書を含む勉強のために … 続きを読む 「未来のモノのデザイン」を読みました
昨日、オルセー美術館展2010に行ってきました。ぜひ行きたい、と意気込む母親の意向(?)で両親と一緒に。 オルセー美術館展2010ではゴッホの自画像など、誰でも知っている名画と呼ばれる作品が多く展示されています。その上に … 続きを読む オルセー美術館展2010に行ってきました
ブログのデザインを更新しました。WordPress標準添付のClassicスタイルを元に、スタイルシートを書き換えて碧落の配色に変更しただけです。 とりあえず体裁は整いましたので、本日より公開してみます。 続きを読む ブログのデザインを更新