« 2009年09月 | メイン | 2009年11月 »

2009年10月 アーカイブ

2009年10月01日

エイプリルフールとアクセシビリティ

普段と違って至極真っ当な話をする。
これは、学生だった頃、インターネットでエイプリルフールの特集を見ていた時にふと懸念した事で、当時は「アクセシビリティ」という言葉を知らなかったし、ここまでエイプリルフールが加熱するとは思いもしなかった。
しかし、毎年エイプリルフールを迎える度にこの事を思い出し、懸念は深まるばかりである。
エイプリルフールまで後半年となったので、エイプリルフールとアクセシビリティについて思っている事を書く。
まずはじめに、本題からは脱線するが、「障害者」という言葉について、私の考えを述べておく。
近年、「障害者」を「障がい者」と書く傾向にあるが、私は「害」という言葉を除いた所で、言葉を使う者が「障がい者」という言葉を差別的に使う限り、差別はなくならないと考えている。
「障害者」は「障害」を持った「者」であり、決して「害」を持った「者」ではない。
漢字が与える印象が悪いからと言って「障がい者」と書き変えた所でなんの問題解決にもならない。
過去には、「精神分裂病」が「統合失調症」と呼び変えられた例があるが、これも同様で「精神分裂病」という言葉を差別的に使用していた者が居たように「統合失調症」という言葉を差別的に使用する者が居ればなんの解決にもならない。
ただし、「精神分裂病」という名称のため、「統合失調症」に対する偏見が助長されていた歴史があるため、「障がい者」と一律に比較する事ができないが...。
また、情報処理上・アクセシビリティ上も「障がい者」は余り良い影響を与えるとは思えない。
上記の事から、この記事では以後、「障がい者」ではなく敢えて「障害者」と記述することをお断りしておく。
以下、本題。
毎年、エイプリルフールには、各サイトが趣向を凝らす特設ページ(トップページを置き換えるサイトもある)を披露する事が定番になってきている。
年々その内容は凝る一方で、一見しただけでは嘘なのかどうかも見分けがつかない場合がある。
4月1日を過ぎて、うっかりエイプリルフール用のニュースリリースを開いてしまうと信じてしまいそうになる。
サイトによっては、最後まで読まないと気付きにくかったり、下手をするとURLの中に「april」や「0401」の文字を見ないとわからない場合もある。
エイプリルフールを過ぎると削除される場合もあれば、「この企画は終了しました」というような内容に置き換わる所もあるが、そのまま手を加えず残している場合もある。
エイプリルフールのニュースリリースの中で、よくできた特設ページと思う今でも読めるものを挙げてみよう。
この2002年のリリースを2009年10月に読んで、エイプリルフールのものと気付く人がどれだけいるだろうか。
確かに「この特集は終了しました。」とは書いてはいるが、特集がエイプリルフールだとは書いていない。
読み方によっては、『「宇宙広告プロジェクト2002」の特集が終了した』ようにもとれる。
健常者はまだいい。
ウェブブラウジングに音声ブラウザ・スクリーンリーダーを使用している視覚障害者、あるいは知的障害者はどうだろうか。
(ウェブサイトの識別についての話題のため、内蔵疾患や四肢の障害等を持っている方々はここでは健常者側としている。もしかすると、視覚及び分析能力の障害を総称するような用語があるのかもしれないが、私の無知故的確な用語を思いつかなかったためお許し頂きたい。)
既に書いたが、サイトがエイプリルフールのページの面白さを競うようになり、段々と内容がリアルになってきている。
次にあげるのは今年のエイプリルフールの特設ページである。
またYahoo! JAPANの例で関係者には申し訳ないが、エイプリルフールの特設ページとして良くできている挙げさせて頂く。
ひとつ目のページは見た目でエイプリルフールの特集と表記があるのはページのずっと下であり、URLからは判断がつかない。
ふたつ目のページは、ひとつ目のページで映像が流れた後に表示される。
このページでは、「スタジオカラーからのメッセージ」内に「エープリルフール企画」、右上に表示される日付の横に小さく「(エープリルフール)」、フッタの近くの協力した企業のところと更に下のコピーライト付近に「エープリルフール」の文字がある。
しかも、ヱヴァンゲリヲンとの企画のため、黒と白と赤を基調としたコントラストが非常に強いページである。
赤が強烈に目に映えるため、白く書かれた文字が若干目立たなくなっている。
(読む時は白い文字が読みやすいが、意識しないと赤い文字にばかり意識が向いてしまう。)
悪い事に「エープリルフール」と書かれているのは、全て白い文字である。
このような状態は健常者でも気付きにくい状態であるのに、障害を持っている方々が情報の真偽を容易に判断できるとは思えない。
また、HTMLを見るとスクリーンリーダーにも辛い構成となっている。
ひとつ目のページのHTML上では、全162行中149行目まで辿らなければならない。
ふたつ目のページのHTML上で言うと、全375行中、189行目、318行目、361行目に当たる。
(「スタジオカラーからのメッセージ」は227行目に当たるが、FlashであるためHTML上では判断できない。)
Wikipediaにはエイプリルフールの特集へのリンクがあり、他のエイプリルフールの特設ページも見る事ができる。
機会があれば、アクセシビリティの観点から一度ご覧になって頂きたい。
さて、そろそろエイプリルフールのページとその他のページを容易に見分けられる何かが必要ではないかと思う。
これは障害者に留まらず、健常者にとっても同様である。
将来、特設ページが閲覧される可能性も考慮すると尚更だ。
また、当ブログのような個人サイトならともかく、ニュースサイトやポータルサイト内に極わずかではあるが、誰もがそれが真実と認めないエイプリルフールの特設ページがその他のページと混在しているのは問題ではないだろうか。
エイプリルフール用の折角の特設ページを消してしまうのはもったいない。
ただ、容易に判断できれば良いのではないだろうか。
この件について、私はこれは素晴らしいと言えるようなアイディアを持ってはないが、ふたつ提示してみようと思う。
究極的に言えば、機械的に処理できれば良いと思う。
例えば、meta要素やマイクロフォーマットに埋め込む方法が考えられる。
但し、機械的に処理するために各サイトで統一する必要がある。
また、これらを処理するブラウザ側の対応が必要になってくる。
これは大掛かりであるし、全体の足並みが揃わなければ実現できないであろうからあまり現実的ではない。
次は、容易に実現でき、個々のサイトの心遣いで対応可能な方法である。
エコマークやグリーンマークのようなアイコンを作成する。
エコマークのような淡い色ではなく、目立つデザインが良いと思う。
ただし、サイトのデザインもあるため、色は規定せず(但しコントラストの規定は必要)に形状を目立つようにしたほうが良いのかもしれない。
形状に重きを置き、色を柔軟にしているのは、後述する表示位置を考慮しているためである。
このアイコンは個人でも企業でも自由に利用できるようにするため、パブリックドメインが望ましい。
パブリックドメインであれば、全てのエイプリルフールの特設サイトで統一したものを使用できるよう促す事ができないだろうか。
クリエイティブコモンでないのは、未だにクリエイティブコモンに対しての理解が得られない企業が存在すると思われるため、普及促進を優先してパブリックドメインとする。
次がこのアイディアの重要な部分かもしれない。
このアイコンを次のようなタグで表示させる。
<img src="april_fool.png" alt="注意:これはエイプリルフールの特設ページです" />
ファイル名は仮に「april_fool.png」としたが、ファイル名はサイト別で違っても問題はないはずだ。
重要なのは、スクリーンリーダーが認識するalt属性とその値である。
そして、タグを埋め込む場所は、body要素の直下の一番最初か本文の先頭部分が良い。
この位置であれば、アイコンを探すのが比較的容易であるし、スクリーンリーダーに対しても効果的だろう。
上記のような稚拙なアイディアしか挙げられないのが残念ではあるが、より良いアイディアの叩き台となればと思う。
もちろん、もっと良いアイディアがあればと思う。
説明不足の部分もあるかと思うが、以上がエイプリルフールとアクセシビリティについて私が考えている事を書き出してみた。
ふたつ目のアイディアは、現場の努力で実現できるレベルであると思うので、普及しないだろうかと考えて(妄想して)いる。
後、誰がどのようなアイコンを作成するか...。

2009年10月05日

正規表現をエスケープする方法のメモ

Javaの場合
引用を表す「\Q」と引用の終わりを表す「\E」で囲む
import java.util.regex.Pattern;
class SampleEncodeRegExp{
    public static void main(String[] args){
        String escapedRegexp = Pattern.quote("a.c");
        System.out.println(escapedRegexp);                  //=> \Qa.c\E
        System.out.println("a.c".matches(escapedRegexp));   //=> true
        System.out.println("abc".matches(escapedRegexp));   //=> false
    }
}
Rubyの場合
メタキャラクタに「\」を付加してエスケープする
String escapedRegexp = Regexp.quote("a.c")
puts escapedRegexp                      # => a\.c
puts "a.c" =~ Regexp.new(escapedRegexp) # => 0
puts "abc" =~ Regexp.new(escapedRegexp) # => nil

String escapedRegexp = Regexp.escape("a.c")
puts escapedRegexp                      # => a\.c
puts "a.c" =~ Regexp.new(escapedRegexp) # => 0
puts "abc" =~ Regexp.new(escapedRegexp) # => nil
JavaScriptの場合
「\W」(英数字以外)を置換する、つまり記号とマルチバイト文字をエスケープする
JavaScriptの正規表現は、エスケープされても意味をなさない場合にはエスケープそのものが無視される(?)
var escapedRegexp = "a.c".replace(/\W/g,"\\$&");
alert(escapedRegexp);                           // => a\.c
alert(new RegExp(escapedRegexp).test("a.c"));   // => true
alert(new RegExp(escapedRegexp).test("abc"));   // => false
JavaScriptについては以下のentryのコメント参照

2009年10月06日

Bookmarxy - iPhone用ブックマークレットの開発用Proxy

iPhone/iPod touch用のブックマークレットを書くのは相当面倒。
iPhone/iPod touchの独自拡張機能、特にジェスチャー系のイベントを利用したい場合、実機上で動かしながら開発したい。
ブックマークレットを、テスト用のページにscript要素で埋め込んで開発する方法もあるけど、色んなサイトで実行させながら開発を行ないたい事もある。
そんな時は、次のようなブックマークレットをiPhoneに登録し、開発環境のwebサーバ上にあるブックマークレットを実行させる方法がある。
(
    function(){
        var bookmarklet_url="ブックマークレットのURL";
        var script_tag=document.createElement("script");
        script_tag.src=bookmarklet_url+"?date="+(new Date()).getTime();
        script_tag.type="text/javascript";
        var heads=document.getElementsByTagName("head");
        var insert_point=heads.length>=1?heads[0]:document.body;
        insert_point.appendChild(script_tag);
    }
)();
この方法で対応可能な場合もあるが、レイアウトを変更するようなブックマークレット開発の場合はページの再読込とブックマークレットの実行が必要で少々手間だ。
そこで、再読込だけでブックマークレットまで実行してくれるプロキシサーバを作ってみた。
名前は、Bookmarklet+Proxyで「Bookmarxy」。
参考にしたのは以下のサイト。
当初、gzipについては全く考慮していなかった。
また、今回は存在しないurlを指定してブックマークレットを読み込んでいるため、HTTPステータスが200を返さない。
このため、正常に動作するJavaScriptが返っても意図した通りに実行されなかったので、HTTPステータスを上書きしている。
gzipとHTTPステータスを解決できたのは、nankiさんの助言のおかげ。
実行環境
iPhone/iPod touchは開発用ウェブサーバと同じネットワークにWi-Fiで接続している事を想定。
設定をうまくやればウェブサーバがインターネット上にあっても可能なはずだが、接続元を制限していないためこのままではセキュリティ的に非常に危ないので、必ず接続元を指定する事。
3G環境ではプロキシを設定できないはずなので対象外。
rubyの標準添付ライブラリに含まれているWebrickというWebサーバを使用しているため、rubyの実行環境が必要。
開発で用いたのは、Ruby1.8.6とWEBrick 1.3.1。
使い方
適当なディレクトリに保存し、実行権限をつける。
LANからインターネットに出るために、プロキシが必要なのであれば、61行目の「:ProxyURI => URI.parse('http://parent_proxy_url:parent_proxy_port/'),」の部分のコメントを外し環境に合わせて書き変える。(開発環境にProxyがないため確認はしていない。)
「bookmarxy.rb」と同一ディレクトリに「bookmarklet.js」というファイルを作成する。
「bookmarklet.js」にブックマークレットを以下のようなフォーマットで記述する。
bookmarklet.js
(
    function(){
        //ここにブックマークレットの本体を記述
    }
)();
ターミナルから「bookmarxy.rb」を実行する。
iPhone/iPod touchの接続先のプロキシ設定に、Bookmarxyが起動している端末のアドレスとポート「8118」を指定する。
iPhone/iPod touchのSafariでサイトにアクセスすると、(ほぼ)全てのページで「bookmarklet.js」内のブックマークレットが実行される(はず)。

2009年10月11日

ミネラルウォーター

海洋深層水買った。
けど、味が普通の水と変わらない。
あれ?
配合?
えええ?
0.4%?
えええええ???
河川水?
深井戸水?
普通の水道水と変わらん!!!
海水0.4%で「海と大地の湧昇水」ってつけるか普通...。

2009年10月18日

有須子がtwitterに出現

有須子は少しずつインターネットを浸食してきました。
コナミコマンドにも...。
UbiquityにもMinibufferにも...。
AutoPagerizeにまで...。
そしてとうとうTwitterを浸食しはじめました。
インストールするとTwitterのユーザが有須子になります。
適応前
適応前
適応後
適応後
更に拡大した有須子の世界をご堪能下さい。
技術解説
実は今回と同様の効果を望むだけであるならmainを次のようにしておくだけでいい。
var main=function(doc){
    var o=doc.getelementsbyclassname("tweet-url profile-pic url");
    for(var i=0;i<o.length;i++){
        var image=document.createelement("img");
        image.setattribute("style","position:absolute;top:0px;left:0px;");
        image.setattribute("src",image_uri_usuko_frame);
        o[i].appendchild(image);
    }
}
しかし、今回は敢えて複雑になっている。
その理由は、単に画像を重ねて表示して表示するのではなく、画像そのものを合成したかったからである。
Usutotter実行後の画像を調べてみるとわかるが、img要素を重ねて表示しているのではなく画像が置き換わっている。
これはユーザアイコンをCanvasに描画し、その上に有須子のフレームを重ねて描画することで実現している。
有須子フレームはアルファチャンネル付きのPNGをBase64化したものを使用しており、フレーム内部も薄暗くなるようになっている。
しかし、TwitterのユーザアイコンのURLは「twitter.com」とは別ホストのため、そのままではCanvasに読み込めない。
このため、ユーザアイコンはSame Origin Policyの制限がないGreasemonkeyのXmlHttpRequestを経由でBase64化したものを取得し使用した。
このあたりの制限については以前書いたので興味があれば次のリンクを参照。
理想を言えば画像の端を有須子のフレームの形にしたいのだけど、Canvasは合成時にはアルファチャンネルに対応していても、Canvas上で直接アルファチャンネルを操作する事はできないようだ。
このためプロファイル部分の画像がこのようになってしまう。
ブロファイルのアイコン
ブロファイルのアイコン
clipメドッドを使えば描画領域を決められるが、一度描画してしまった位置を透過にはできない模様。
また、今回の場合はパスではなく画像を使ったマスクの方が適しているのだが、それにも対応していない。

2009年10月24日

C#の絵本を読んで

「C#の絵本」を読んでの個人的メモ兼簡単な書評。
挿絵も工夫されていて、読みやすい本だった。プログラム初心者にも安心して勧められると思う。他の絵本シリーズも読んでみたくなった。ただ、サンプルコードの品質が気になった。プログラム的には問題ない場合が多いけど、文言が問題だと思う。詳細は後述のメモと実際に本を手に取って確かめて欲しい。
以下、思った事を列挙。メモ内の例は基本的に書籍とは異なっている。
[xi]
覚えておきたい用語 「JIT(Just In Time)コンパイラ」。「Just In Time」は「逐一」という意味。
[xi]
覚えておきたい用語 「中間言語(IL:Intermediate Language)」。
[P2]
覚えておきたい用語 「エントリポイント」。プログラムの実行開始点の事。
[P16]
2次元以上の配列で、同一次元の要素数が異なる配列をジャグ配列というらしい。
[P17]
ジャグ配列の例
    int[,] ary = new int[3,4];                                  //ジャグ配列ではない(呼称不明)
    int[][] ary = new int[][]{new int[]{1,2},new int[]{3,4,5}}; //ジャグ配列
[P19]
列挙型の例
    enum Sample{apple,box,cat=10,desk};
    Sample s;
    s=Sample.apple;
    Console.WriteLine(Sample.box);      //=>box
    Console.WriteLine((int)Sample.cat); //=>10
[P33]
「&&」「||」は不要な評価はしない。短縮評価と言うらしい。「&」「|」は全て評価される。ビット演算子以外にも使えるようだ。
[P38]
checked文を使うとオーバーフローを起こした時に例外を発生させる事ができる。逆にunchecked文はオーバーフローを無視する。通常はuncheckedの状態。
[P70~P71]
ブロックの内外で同じ名前の変数は宣言できない。但し、クラスのフィールド名とローカルの変数名は同じでも構わない。この時、ローカルからフィールドを参照するには「this.[フィールド名]」を使う。
[P77]
この実行例、ちょっと微妙。引数の文字数によって出力位置が変わるため、メソッド内にスペースを固定で埋め込んで表示位置を調整している。こんな事するぐらいなら引数の文字数を揃えた方が良い。
[P82]
コピーコンストラクタはcloneメソッドでは駄目なのだろうか。それともcloneメソッドがないのか?
[P84]
JavaScriptだと、フィールドとプロパティの違いは余り意識しなくても使えるため、用語も結構混同して使ってしまっている。本来は違う概念だし、C#では書き方も違う。
[P86]
インデクサというのは初めて聞いたかもしれない。プロパティと配列が合わさったようなものと理解した。
[P88]
Mainメソッドの戻り値は通常voidであるが、intに変更すると正常終了したかどうかを返す事ができる。0の時は正常終了。
[P89]
コマンドライン引数はMainメソッドが文字列配列として受け取る。
[P102]
継承させたくないクラスにはsealedをつける。Javaでいうfinalみたいなものか。
[P103]
この実行例も良くないと思う。買い物をするような例なのに、所持金がマイナスになっている。「if (money + In - Out < 0)」で判定後、elseの中で「money = money + In - Out;」とする方が良いと思う。
[P105]
親クラスのコンストラクタに引数がある時、子クラスのコンストラクタで親クラスのコンストラクタを指定するには「base」を使う。
    class Child : Parent{
        public Child(int i) : base(i){}
    }
[P106]
親クラスのメンバと同じ名前のメンバを子クラスで宣言したい時は、newをつけなければならない。別のキーワードはなかったのかな。オブジェクト生成と紛らわしい。
[P107]
親クラスはbaseで参照可能。newで親クラスのメンバを隠匿している時もbase経由で参照できる。
[P108]
オーバーライドが前提のメソッドにはvirtual修飾子を使う。仮想メソッドというらしい。抽象メソッドと何が違うのか不明。
[P108]
virtualで宣言された親クラスのメソッドはoverride修飾子をつけて上書きする。
[P111]
実行結果に「3文字分のスペースがあく」とあるが本当にあくのだろうか。char配列を初期化した後、0~2の要素には何もしていないので値はnullのはず。Console.Writeにnullを渡すと半角スペースを出力するような仕様になっているのだろうか。
[P114]
サンプルプログラムは微妙。
「定規」のクラスなら角度と長さは正負のバリデーションが欲しい。せめて「図形」クラスを例にしたほうが良かったのではないか。素材は色で代用できるはず。後、TriangleRulerのgetInfo内の日本語部分、「°」が「。」になっている。
[P116]
C#ではメソッドの呼び出しは基本的に値渡し。意図的に参照渡しにしたい時には、呼び出し元・呼び出し先共に「ref」が必要らしい。どちらかだけに「ref」がついていたらどんな動きをするんだろうか。クラスはそもそも参照型なので、必然的に参照渡しになるとある。多分これは、アドレスへの参照を値渡しするためこのようになっているはず。「ref」に似た「out」というものもあるが、こちらは引数として渡す前の代入が不要らしい。
[P119]
多態性(ポリモーフィズム)の概念を10年ぐらい勘違いして覚えていた。「あるクラスの性質が継承によって他のクラスに広がっていく事」だと思っていた。正しくは、「あるクラスが継承によって他のクラスの様にも振る舞える事」を指すらしい。逆にこの性質に名前があったんだという印象で、継承の利点のひとつとしか捉えていなかった。
[P121]
抽象クラスの抽象メソッドの上書きにもoverrideが必要らしい。
[P122]
インターフェイスの抽象メソッドの上書きにはoverrideは不要らしい。
[P122]
インターフェイスを実装するためには「:」を使う。これはクラスを継承するときと同じ。Javaでは両者を文法上、区別するがC#では区別しない。
[P123]
インターフェイス定義の抽象メソッドは、インターフェイスの実装側で全てが必ずpublicで実装されなければならないため、publicは省略できる。
[P123]
インターフェイスを複数実装する時は「,」で区切る。クラスを継承しつつインターフェイスを複数実装するには、どう書くのだろうか。
[P125]
インターフェイスがインターフェイスを継承する際に、同名のメンバがある場合、継承先の抽象メンバを優先的に扱うために「new」をつける必要がある。
[P132~133]
オブジェクトクラスに値型のデータを代入する事をボックス化(boxing)、逆にボックス化されたデータを値型に戻す事をボックス化解除(unboxing)と言うらしい。int型をボックス化すると、内部ではInt32構造体の形で保存されるらしい。
    int i=1;
    Object o=i; //ボックス化
    int j=o; //ボックス化解除
[P134~135]
Javaでいうパッケージの概念はC#ではnamespaceを使って実現するようだ。Javaではpackageの宣言文だが、C#ではnamespaceブロックを使う。名前空間の階層はnamespaceブロックのネストで対応できる。階層が深い名前空間は、インデントが深くなり過ぎてコーディングがしにくそうという印象を受けた。宣言で対応できる等の別の仕組みがあるのかもしれない。(以前見たjavaScriptで名前空間を強引につくる方法を思い出した。)
[P136~137]
javaのimportと同じ事は、C#ではusingで宣言する。「using S = Sample;」のように別名をつける事も可能。
[P140]
is演算子は「is a」「has a」のisの事かも。「a is A」は「aはAの一種」という感じか。as演算子は型変換。「B b = a as B;」のように使う。キャストとの違いは型変換不能の時の動作で、キャストは例外となるがasはnullを返すところ。
[P147]
throw文の説明にあるコード内、catchで受けているExceptionの変数名とcatch内で宣言されているExceptionの変数名が同じになっている。コンパイルエラーになりそうだ。
[P156]
StreamWriter型の変数wのメソッドCloseのカッコが閉じられていない。
[P163]
桁数の指定の説明のはずなのに、実行例が微妙。数値の桁が指定された桁数よりも小さいため、サンプルがほとんど意味をなしていない。
[P164]
Emptyフィールドの用途がわからない。「string c = "";」と何が違うのだろうか。
[P171]
またまたサンプルが微妙。正規表現が"C.*の絵本"なのに結果の文言が「C#の記述があります」となっている。これだと「Cの絵本」でも「COBOLの絵本」でも一致するため、「C#の記述があります」と表示されてしまう。
[P175]
ここもサンプルが...。問題が3文字未満だった場合、ヒントのところがおかしくなる。問題を読み込む時に3文字以上でないと読み込まないようにするとか、3文字以上でないとヒントは出さないとか、せめて「問題は3文字以上になるようにして下さい。」と注意書きを入れるとか、何らかの手を打っておいて欲しかった。
[P176]
デストラクタの定義方法は「~(チルダ)」をつけたクラス名と同じメソッド。Javaではfinalizeなんだけど、ここではC++の文法が採用されている。Javaではfinalizeが実行される前にJavaVMが終了する事もあるらしいけど、C#ではどうなのだろうか。
[P178]
ジェネリッククラスはダッグタイピングのような事をするための仕組みと理解した。
[P180]
デリゲートを使うと、メソッドを高階関数のようにできるようだ。
[P180]
「DelegateClass dc = new DelegateClass(method);」は「DelegateClass dc = method;」とも書けるらしい。
[P181]
デリゲートのマルチキャストについて書かれているが、どう便利なのかが理解できない。メソッドをふたつ追加したデリゲートに引数を渡して実行するとどうなるのか、最初に実行されるメソッドの戻り値はどうなるのか等、もう少し詳細な説明が欲しいところ。
[P183]
イベントでのデリゲートの使い方を見ていると、JavaScriptのaddEventListenerとremoveEventListenerに近い使い方をしている。プロパティの宣言と似ているadd/removeを使ったeventの宣言例は、正にそんな印象を受ける。そもそも、デリゲートのマルチキャストは、イベントを想定してのものなのかもしれない。
[P185]
ひとつ目のWriteLineの第一引数の引用符が閉じていない。
[P186]
プリミティブ型は通常nullを許さないが、null許容型(Nullable Type)で宣言する事でnullを代入できるようになるらしい。書き方は「int? i = null;」で、これは「System.Nullable<int> i = null;」のsyntax sugerとの事。つまり、null許容型はジェネリッククラスで実現されているということらしい。
[P187]
null許容型はふたつのプロパティを持つ。nullの時にfalseを返す「HasValue」と、値を返すがnullの時は例外となる「Value」。
[P187]
値型の値をnull許容型の変数に代入する時は暗黙の型変換が行われる。逆にnull許容型の値を値型の変数に代入する時は明示的にキャストしなければならないらしい。ただし「??」を使いnullであった時の値を定義しておけば、キャストは不要になる。「int? i = null;int j = i ?? 0;」
[P202]
Visual C#で生成したプログラムは次のようなディレクトリ構成になるらしい。
    ドキュメント
     ┗Visual Studio 2008
      ┗Projects
       ┗[ソリューション名]
        ┗[プロジェクト名]
         ┣[ソースファイル]
         ┗bin
          ┣Debug
          ┃┗[Debugモード実行ファイル]
          ┗Release
           ┗[Releaseモード実行ファイル]
[P203]
環境変数Pathに「%SystemRoot%\Microsoft.NET\Framework\v3.5」と登録しておくと、コマンドプロンプトから「csc [ソースファイル名]」でコンパイルできるようになるらしい。

2009年10月31日

iPhoneアプリ不要 iPhone/iPod touchからブラウザ経由でマウスをエミュレートする「Ajax Mouse」

iPhoneアプリの「Air Mouse Pro」の値下げに伴い、人気が再加熱している模様。
でも、これってiPhoneのMobile Safariのtouchイベントで、簡易的なものが可能なんじゃないのかなと思ったので作ってみた。後述の注意事項に書かれているような問題があるため、現時点では開発者以外は手を出さないほうが懸命です。
経緯
ここは読みとばしてもらって構わない。経緯をざっくり説明。上記の通り、Air Mouse Proと同等の機能が、Mobile SafariのtouchイベントとAjaxとWebサービスで作れるのではないかと考えたのが最初。以前プロキシを作った時に、Rubyの標準添付ライブラリのWebrickというサーバが簡単だったのでこれを使おうと思っていた。Macでマウス操作をする方法を探していて、CoreGraphicsのCGEventCreateMouseEventというものを使えば良いことまで調べた。CoreGraphicsをRubyCocoaから操作できるのであれば、この方法で行こうと思ったのだけれども、CoreGraphicsの資料があまり見つからない。特にイベントまわりの資料が少ないようだった。「JavaのRobotなら資料があったのになぁ」と思った時に、「じゃあJavaで実装すれば良い」と思いつきJRubyでの実装に走りかけたが、そもそのサーバもJavaにすればJavaだけでいけると気付いた。でも、tomcatはちょっと大袈裟すぎないかなとTwitterにpostしたら、JettyとWinstoneというものを教えてもらった(thx! @keisuke_n @nanki)。どちらも軽量なWebサーバで、使い勝手もよさそう。Winstoneは、サンプルと一緒に配布するようなスタイルに向いているとのことだっtので、Winstoneを使う事に決めた。
注意事項
とりあえず、動作する事を目標としたのでエラー処理やセキュリティについては全く考慮していない。JSPを使っていないため、JSPに関連したライブラリはimportしていない。領域外の判定が面倒だったため、マルチディスプレイには対応していない。また、アクセスする度にRobotオブジェクトを生成しているため多分効率が悪い。ロボットをインスタンス変数にしてコンストラクタで初期化したかったのだけどやり方がわからなかった。WebサーバのWinstoneと相性が悪いのか、そもそもServletじゃインスタンス変数やコンストラクタが使えないのか、とにかく解決策が見つからなかったので、Ajaxでアクセスする度にインスタンス化している。反応が悪いのはこのせいかもしれない。あと、jar化してもwar化も動作しなかった(そもそも動かし方を理解していない可能性も...)ので、ソースそのものを公開しておく。使用しているWinstoneのライセンスが複雑でよくわからないが、LGPLも選択可能なようなので、Ajax Mouseは一応MITライセンスとしておく。等々、とりあえず問題は山積しているけど、これらを解決するスキルがないため、開発の継続は今のところ考えていない。実証コードというか、コンセプトのコードというか、とりあえずそんな位置付け。これを見てもっと良いやつを誰かが開発してくれたらなぁってところ。
実行方法
ソースはgithubにEclipseのプロジェクトを公開しているので、そちらから入手して下さい。Winstoneはライセンスが不明瞭だったので同梱していません。別途、Winstoneのjarを入手し、ビルドパスのライブラリに追加して下さい。ポートはソース固定で8080になっています。コンパイル後、AjaxMouseクラスを実行して下さい。iPhone/iPod touchのSafariで「http://[サーバのアドレス]:8080/」にアクセス。アクセスと同時にAjaxMouseが起動します(何故、AjaxMouseを実行した時点で起動しないのかは不明)。画面上部にトラックパッド、画面下部の左右にマウスボタン、画面下部の中央にホイールが表示されます。後は、操作するだけです。
ソース
ソースは以下から入手可能です。
Winstone
Winstoneのjarを以下から入手し、ビルドパスのライブラリに追加して下さい。
参考にしたページ