UIにおける一つの真理

ユーザーは何度でもボタンを押したがる!

古いサービスの保守をやっている中で、ユーザーからのクレームないし調査依頼のうち一定の割合を占めるのが「同じ操作がいつの間にか二重で行われてしまった」というもの。命名するなら「過失による多重POST問題」。

コメントの多重投稿程度ならまだしも、それが決済に関わるような操作においても平気で*1二重クリック、三重クリックとしてしまって、それが後々問題になるパターンは多い(月会費を二重に売上してしまったとか)。「時間がかかりますのでボタンは必ず一度だけ押してください」なんて注釈が書いてあっても、そんなの関係ねぇ!

大方リクエストの間隔が1秒未満とは限らないところを見ると、いわゆるダブルクリック操作をしているというわけではなく、なかなか画面が切り替わらない間に「ボタンまだ押してなかったかな?」みたいな感覚で(あるいは無意識で)何度もカチカチとクリックしている光景がなんとなく想像できる。概ねユーザーのPCリテラシーが低いほど何度もボタンを押したがる傾向があるが、これがIT系のエンジニアであったりしても長期に渡って利用していると大抵一度や二度は遭遇するように思う。

個人的にリクエストの待機中に同一のリクエストを何度でも実行できてしまうのはブラウザ側の問題だと思っているが*2、多重に実行されると困る処理については、JavaScriptで多重送信を防ぐ対策を入れるなり、サーバ側で短時間かつ同一内容のリクエストは弾くといった対策を施しておくのが現実的な解か。

*1:おそらく気付いてないだけだとは思うが

*2:サーバからのレスポンス待ちな状況で再度同じリクエストを行いたい場面なんて、DoSくらいしか考えられない。せめてダイアログくらい出すべきじゃ?

任意の一文字を表す正規表現

任意の一文字を表すメタ文字「.」は、忘れがちだけど改行文字だけは含まない。これはPerlでもPHPでもJavaScriptでも共通。

var re = new RegExp('q[qrwx]?(\\W).*?\\1', 'gm');

上記はPerlのquote表現である qw/.../ 等にマッチするが、複数行にまたがっている場合はマッチしない。

真に任意の一文字を表すには、BKっぽいけど文字クラス[\s\S]で可能。

var re = new RegExp('q[qrwx]?(\\W)[\\s\\S]*?\\1', 'gm');

(?:\s|\S)の方が高速かも。

PerlとPHPのシンタックス差異

ものすごく久し振りにPHPでコードを書く必要性に迫られているのだけど、Perlに慣れ過ぎていて些細なシンタックスで躓きまくり。

  • sub {} ではなく function() {}
  • elsif ではなく elseif
  • splitの分割パターンはquoteで与える(正規表現が必要ないならexplodeを使う)
  • eq や lt のような文字列用の比較演算子は存在しない
  • 局所変数の宣言が存在しない
  • ヒアドキュメントの記述が微妙に違う
$text = << "end_of_text";
(Perlの場合)
end_of_text
$text = <<< end_of_text
(PHPの場合)
end_of_text;

新しい言語に手を染める際は、こういう身体に染み付いてる箇所で引っ掛かるうちが辛い。いや、PHPは一時期結構やってたはずなんですけどね。

First 13 Programs on New Install

つい先日に某ショップブランドの新しいPCが到着。マシンの新調は確か三年ぶりくらい。OSはVistaにするメリットを感じなかったのでXPを選んだのだけど‥‥DirectX 10がVista限定ということを今更知って、いずれ後悔することがあるような予感。念願のデュアルディスプレイを実現して感激するも、併せて買った机に並べたら思ったより手狭だったのがちょっと哀しい。今度コンパクトなキーボードを買おうと思った。

折角なので、新調してから最初にインストールしていったソフトのメモ。

とりあえず

  • JWordのアンインストール

(スコア:-1, 余計なもの)

メッセンジャー

Windows Messengerが何かと邪魔くさいので、ずっとこちらを使ってます。プラグインもいくつか入れてたはずだけど、Logger以外思い出せないので後回し。そういえば、もう数年くらいIRC使ってないや。

ブラウザ関連

最近GmailHotmailしか使ってないので、特にメーラーを入れる必要もないことに気付いた。職場ではBecky!使ってるど、仕事関連のメールは家では見ません。

アーカイバ

  • Lhaplus

未だに何かしら入れておかないと他のアプリを入れられなかったりするので困ったものです。主要な圧縮形式くらいOS標準で実装してくれればいいのに。

ネットワーク関連

ftp,scp,sshクライアント。他2つには満足してるんですが、WinSCPは過去に何かと問題があったので代替があれば乗り換えたいところ。

テキストエディタ

十年来に渡って秀丸を愛用してきたけど、最近vimに乗り換えました。タイプミスで何が起きたかぱっと判らないとこが怖くて敬遠してたけど、慣れてくると断然便利だった。今では秀丸シンタックスハイライトや単語補完とか実装されてて、コーディングには困らないんですけどね。

その他

ランチャーはWin98の頃からCLaunch使ってます。久々に入れ直したら、機能がえらく増えててちょっとビックリ。

昔と違って構成ハードのドライバを無理に全部入れて回る必要とかないから、セットアップも楽になりましたね。開発向けのActivePerlやmakeができる準備、手持ちのMacromedia(じゃないAdobe)製品のインストールとかはまた後日にちょっとずつ。

暗黙の第一引数invocant

すぐ名前を忘れてしまうのでメモ。Perlではオブジェクトのメソッド呼び出しにおいて、暗黙の第一引数として呼び出し元のオブジェクト情報が渡る。これをinvocantと呼ぶ。

sub method {
    my $self = shift;
}

invocantは上記のようにshiftで受け取るのが慣例。クラスから呼び出された場合はパッケージ名が、インスタンスから呼び出された場合はオブジェクトのリファレンスが渡される。

ちょっと調べてみたら、このinvocantというのは英和辞書にもあまり載っていない単語で、「invokeする人」という程度の意味らしい。invokeはメソッドやサブルーチンを呼び出すという意味の動詞だが、原義は「祈祷や儀式により霊的存在を召喚して術者と一体化すること」だそうで、西洋の魔術がルーツらしい。ちなみに、このinvocationにおいて呼び出す対象はイタコが行う口寄せのように先祖の霊などではなく、精霊だとか悪魔だとかだそうな。

プログラムと魔術は意外と関連が深いんです。たぶん。

jQueryでDOM要素を組み立てる

上記の例はご紹介する$.N()メソッドをjQueryと一緒に使うと以下のように書けるようになります.

$('body').append(   
  $.N('a', {   
    className: 'external',   
    href: 'http://www.yahoo.co.jp/',   
    style: 'background-color: #daa;'  
  }, 'yahoo! JAPAN')   
);  

このとき,要素にCSSセレクタクラスを指定するにはclassではなくclassNameを用いていることに注意してください.

http://blog.fulltext-search.biz/articles/2007/09/30/how-to-use-and-dom-tip-for-jquery

jQueryオブジェクトに元々準備されているattr()は、引数を連想配列で与えることで複数の属性を設定できるので、これを使えば似たような形で書くことができます。

$('body').append(
  $('<a>').attr({
    className: 'external',   
    href: 'http://www.yahoo.co.jp/',   
    style: 'background-color: #daa;'
  }).text('yahoo! JAPAN')
);

「className」は引用符で囲むなら「class」で与えて問題ないようです(quoteしておかないとエラーになります)。ただ、style属性はFirefox2では反映されるんですが、IE6では反映してくれませんでした‥‥うーむ。

オブジェクトに対応するHTMLを取得したい

例えば、以下のようなhtmlがあったとします。
<input type="text" name="age" id="age">

これに対し、
var taget = document.getElementById('age');
とすると、HtmlElementオブジェクトが取得できると思うのですが、target.nameとすると「age」が返ってきたり、target.typeとすると「text」が返ってくるのですが、属性情報ではなく、「<input type="text" name="age" id="age">」っていうhtml上での表記を取得したいのですが、その方法が分かりません。

Loading...

IEではouterHTMLというプロパティで取得できるみたいですが、Firefoxでは元々のソースを取得する方法はないらしい。パース前のソースが残ってないのか、それとも取得する方法が失念されてただけなのか?

alert($('target').toString());

だとか、

$('target').html = replaceHtml;

みたいにして使いたいという場面は結構あると思うのになぁ。