検索結果ページは検索ボックスへフォーカスしてほしい

絞り込みたいときに検索ワード打とうとすると、フォーカス当たっていなくてイラってする。GoogleYahoo!(.comも)、goo、Infoseek、livedoor、 Exciteでもフォーカス当たらないので、何か不都合な点があるのかなとも思ったり。逆にはてなとかAsk.jpだと検索ボックスにフォーカスが当たる。
結局、Google用に超単純なGreasemonkey書いたけど、不便に感じる人は少ないのかなぁ。

(function() {
var inputs = document.getElementsByTagName("input");
for (var i = 0, len = inputs.length; i < len; i++) {
if (inputs[i].name == "q") {
inputs[i].focus();
break;
}
}
})();

prototype.jsのbindを理解する

prototype.js使っていてうれしいことの一つにbindが使えるというのがある。$()とかAjaxクロスブラウザ対策とかもいいけれど、thisをbindできるのは大きなメリットだと思う。bindがないとどういう時に苦労するかというと、以下のような場面。

var Foo = function(name) {
this.name = name;
}
Foo.prototype.talk = function(message) {
alert(this.name + ": " + message);
}
function inScope() {
var foo = new Foo("foo");
setTimeout('foo.talk("Hello World!")', 0);
}
inScope();

これは実行できない。なぜかというとsetTimeoutに渡しているfooという変数はinScopeというFunction内でのみ有効だから。メソッドの引数がなければ、関数を直接setTimeoutに登録することで実行自体はできるけれど、今度はthis参照が期待通りに動かなくなる。

function inScope() {
var foo = new Foo("foo");
setTimeout(foo.talk, 0);
}

message変数の部分は諦めたにしても「this.name」までも使えなくなっている。これはsetTimeout自体がthisをwindowとしてcallするため。このthisの問題(仕様だから問題じゃないけれど)は、イベントリスナーに登録した場合も同じで、インスタンス(と呼ぶとJavaScript的には多分間違いだけど)使ったプログラミングをしているとどうしても弊害になることが多い。
そこでbindが必要になる。

function inScope() {
var foo = new Foo("foo");
setTimeout(foo.talk.bind(foo, "Hello World!"), 0);
}

これで「foo: Hello World!」と表示されて、期待通りの動きになる。bindの第一引数にthisとなって欲しいものを渡して、あとは引数を書けば良い。
じゃあprototype.jsがどんなHackをしているかというと、実はHackらしいことはほとんどなくて、JavaScript本来にあるapplyをラップしているだけ。prototype.jsのbindの部分を見てみよう。

Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}

$Aもprototype.jsの機能だけど、簡単に言えば指定されたFunction(上の例ではtalk)のapplyを実行するFunctionをreturnしていて、実行するapplyに対してthisになって欲しいものを第一引数に、受け取った引数(thisとして使うものは省く)を配列にして第二引数に渡している。配列にしているのは、apply自体が第二引数に配列を要求するため。
prototype.jsにはよく似たやつにbindAsEventListenerというのがあって、それは以下のように書かれている。

Function.prototype.bindAsEventListener = function(object) {
var __method = this, args = $A(arguments), object = args.shift();
return function(event) {
return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
}
}

何のことはなく、イベント発生時のevent引数をブラウザ互換をとった上でbindと同じことをしているだけ。
じゃあ、prototype.jsがなかったらどう書けば期待通りに動くかというと、以下のように書けば最初の例が動く。

function inScope() {
var foo = new Foo("foo");
setTimeout(function(){
foo.talk.apply(foo, ["Hello World!"])
}, 0);
}

動くけど・・・というコードだ。
という訳でprototype.jsのbindは素敵だねという話でした。

[追記]
コメントで指摘してもらって気付いたけれど、確かに上の例だと

setTimeout(function(){foo.talk("Hello World!")}, 0);

が書けちゃうので、上の例だと変に短く書けるっぽいアピールになっているので、その辺は訂正します(元コードはそのままにしてる)。コメントで書いてもらってるコードでちゃんと動きます。一応、言いたかったbindのことを、this参照の例で追記しとく。

var Hoge = Class.create();
Hoge.prototype = {
initialize: function(msg) {
this.msg = msg;
Event.observe($("hoge"), "mousedown",
this.mousedown.bindAsEventListener(this)
);
},
mousedown: function(event) {
alert(this.msg);
}
}
var h = new Hoge("hoge");

bind使うとこんなときにmousedown関数内でもthisが継続して使えて、それらしく書ける。勿論、

  initialize: function(msg) {
this.msg = msg;
var self = this;
Event.observe($("hoge"), "mousedown",
function(){self.mousedown()}
);
},

としても動くけれど、一つfunction()を入れ子にするとthisが見えなくなるから、変数に入れる手間が出てくる。

[追記2]
通りすがり2さんのご意見。http://jigen.aruko.net/archives/533/とかのコード見せたほうが良くねって話かな。今のところまだまだ勉強不足なので、凄すぎる使い方が思い付かないけれど、より理解が深まったのでどちらのコメントもどうもです。

PHPの開発にIDEは必要か

昔、PHPEclipseとか使っていた時期もあったけれど、最近は全く使わなくなった。プログラムはWindows上ならEmEditorで書くし、Linux上だとvimで書く。SubversionTortoiseSVN使うか、コンソール上だとそのままsvnのコマンド使うかしてる。エラーはそのまま画面に出すか、エラーログをtailしながらとかしてる。
これで不便に感じることがないのだけど、リファクタリングとかコンパイルエラーの表示とか、そういうのを求めるとIDE使ったほうが良いんだろうか。関数の入力補完とかは普通のエディタでも出来る訳で。
IDE使って嫌なのが、IDEの設定ファイルとかがあれこれ出来たりすること。プロジェクトとして設定とかを保持するのが好きになれない。Subversionから引っ張ってきたら動くよ、というスタンスの方が単純だし、他の人の開発環境が自由になると思う。
JavaEclipseが必要なのは、コンパイルが大きいと思う。Antでビルドしないと、実験的なコードもかけないようなプロジェクトになっていることもあると思うし。あと、Javaだとパッケージ辿って定数見つけたりとかに使うのは便利だと思う。そういうのはPHPだとgrep検索の方が速いかなと感じる(場所の予測が付かないことが多いので)けれど、大規模なPHPプロジェクトだと案外違ったりするものなのだろうか。

退社時に引継ぎ忘れやすいこと

部長の印鑑の場所でもなく、古い契約書なんかでもない。
それは、間近にいる部下のことではないかと思う。辞める前に確認してみよう。自分の部下の成果が目に見える形で後任者に引き継がれているかを。
せっかく頑張ってくれた部下の手柄を知っているのは、貴方だけかもしれないのだから。

JavaScriptのグローバル変数はwindow.から

JavaScript ではいかなる状況でもグローバルオブジェクトにアクセスできる。
ふと思ったのだけど、グローバルなところで以下のコードを書くと、

alert(this === window);

trueなので、グローバルへのアクセスは単純にwindow.でとれるんじゃないかと思う。なので

var global = window;

ではだめ?とか思った。いや、これだとglobalという変数すら意味ないけれど。ちなみに、

function hoge() {
alert(window === (function(){return this})());
}
hoge();

もtrueになる。はい、かなりどうでもいい話でした。

デブサミ2007行ってきた

14日は丸一日行ってたけれど、面白いプレゼンだったのは、竹迫さんid:amachangさんと出張Shibuyaイベントの面々。資料とか内容とかは随時公開されるだろうと思っていたので、特にメモも取らずに聴いていた。
竹迫さんのPlagger話は面白かったけれど、Perl書けなくても大丈夫とかインストールは大変ではないとかが、どうしても資料ベースの説明だと実感できなくて少々残念だった。mixi -> Gmailとかをインストール作業込みで5分でやるデモ映像とかがあったら、論よりデモでRuby on Railsっぽいかなとか感じた。
id:amachangさんの対JavaScript偏見ゼロな視点は聴いていて爽快だった。JSはあれくらい素直に向き合った方が良いと思う。無理やりクラスベースっぽく書く必要もないだろうし、無理やり継承をやろうとする必要もないと思うし。いや、必要であれば、それっぽいことをやるのも勿論ありだけど。JSはプロトタイプベースの素敵さを存分に利用した方が素直なプログラミングになる気がする。言語にはそれぞれの長所があるのだから。
出張Shibuyaイベントはどれも面白かった。最初のDISカッションの内容はまさにそうだし、他のプレゼンにしてもそうだけれど、プログラマじゃないと判り難いかなと思う反面、プログラムが書けることによる可能性の広がりが存分に繰り広げられていたと思う。会場にいた多くの人がそのような感覚を得られたのではないかと思う。

ドラッグ&ドロップのJavaScriptライブラリを作ってみた

Draggable.js

JavaScriptのドラッグ&ドロップは既出でいっぱいあって、有名どころではscript.aculo.usとか、Ricoとかがある。要求仕様がこれらの動きでまかなえれば全く問題ないけれど、もっと違う動きが必要だったりするときに、元が多機能なだけにコードの修正がやり難い。なので、単純にドラッグ&ドロップの実装だけのライブラリを書いてみた。
使い方はリンク先に書いてあるけれど、簡単な使い方をご紹介。

まずはスクリプトをロードして、

<script type="text/javascript" src="./Draggable.js"></script>

position=absoluteな要素を設置する。

<div id="hoge" style="position:absolute;">Hoge</div>

そしてJavaScriptでその要素をnewして終わり。

new Draggable("hoge");

実際のアプリケーションだと、ドラッグ中に下のテキストを選択できないようにしたりだとか、ドラッグしてるものを透過したりだとか、ドロップできる範囲を指定したりだとかが出てくると思う。
それなりにクロスブラウザには作ってはあるので、使えそうであれば、どうぞご利用ください。

アドリブを練習する

心に残るプレゼンは、必ずと言っていいほど事前に用意周到に準備されている
小野さんのエントリを読んで感じたこと。端的に言ってしまうなら「アドリブ」の意味が少し限定的ではないかと感じた。
音楽の例だと判り易いかなと思う。アドリブに変わるものに即興演奏とかインプロヴァイズというような言葉があるけれど、即興演奏は決して「練習されていないパフォーマンス」ではないだろうと思う。元エントリの言葉を拝借させて頂くならば「練習せずに本番に臨む劇団員」ということにはならないだろうと。
洗練されたインプロヴァイズには人を魅了させる(感動させる)力は十二分にあると思う。もちろん、構築美も素晴らしいので、段取りなどを用意周到にして練習することも感動的なパフォーマンス成し遂げる一つの方法だろうと思う。忘れてはいけないのは、その両方とも(アドリブも用意周到も)が「練習された成果物」だということだ。練習していないアドリブは当然存在するけれど、「練習されたアドリブ」という項目があっても良いのでは?と感じた。
しかし、こういってしまうと、アドリブ自体の練習をするべきなのか、用意周到に筋書きして、それを対象に練習するべきなのか、といった分岐に陥ってしまいそうだ。個人的な意見だけれども、例えばプレゼンにアドリブを入れる余地を作らないならば、アドリブの練習は必要ないと思う。逆に、用意周到にしないプレゼンを目指すなら、アドリブの練習をすべきだと思う。要は内容次第で要求される技術が違うだけではないかと思う。勿論、人間的な技術として捉えるならば両方できるに越したことはないのだろうけれど。
アドリブの練習とは何だろうか。これは場慣れとは少し違うと思う。プレゼンで言うならば、思い付いたキーワードを巧い言い回しで繋げたりできるのは、アドリブ技術だと思う。勿論、アドリブの内容を事前に用意周到に準備することは可能だけれど、聴衆の前に立ったときの良い意味での思い付きをオフィスで再現するのは環境的に難しいと思う。どんな練習方法が良いのかは判らないけれど、少なくとも訓練可能なジャンルだと思う。
と、ここまで書いておいてだけれども、プレゼンというジャンル的に、「用意周到」にしておく方が得策なことが多いと思うので、小野さんのエントリタイトルの「心に残るプレゼンは、必ずと言っていいほど事前に用意周到に準備されている」というのは、それはそうだろうなと同感したりする。

近所にビール専門店が欲しい

近所というのは自転車で行ける距離がベスト。近くのスーパーにはベルギービールの欠片もなかったので、近くの酒屋まで行ってきたけれど、ヒューガルデンとギネスが限界だった。とはいえ、せっかく来たのだからと思って買ってきた。

生のギネスはおいしいけれど、ギネスの缶の印象が非常に悪いので、ビンには期待したいところ。あと、お店ではそれ程思わなかったけれど、ヒューガルデンはすごく良い香りがするビールだと、王冠を開けて思った。

[追記]
ギネスのビンは味は良い感じ。でも当然かもしれないけれど泡が駄目だった。ギネスはやっぱり生にかぎる。

Windowsで仕事をする人が覚えた方が良いこと

プログラマのような人はさておき、EXCELとかを使ってWindowsで日常業務を行う人は多いと思う。その割に効率的ではないと思われるアプリケーションの使い方をしている人が多いなと近頃感じる。会社の同僚がCtrl+Sで保存しないというのに正直驚いてしまった。
ということで、「Windowsを使って仕事はできるけれど効率的ではないだろう人」を対象に書いてみようと思う。だらだら書いているので、暇なときにでも。

キーボード入力が苦手でも覚えた方が良いショートカット

キー 操作内容
Ctrl + S 上書き保存(一度も保存していない場合は名前を付けて保存)
Ctrl + C コピー
Ctrl + V 貼り付け(ペースト)
Ctrl + Z 元に戻す
Ctrl + F 検索

これがないと本当に仕事ではきついと思う。コピー&ペーストは流石に知っている人が多いと思うけれど、せっかく作った資料を消しちゃったという経験のある人は、今すぐにでもCtrl+Sで保存を覚えた方が良い。マウスでプルダウンメニューから選んで保存するのは作業の集中力に影響があって、なかなか保存しない人が多い。
あと、元に戻すも非常に重要。入力内容を失敗したときに選択してDeleteとかしている人は覚えた方が良いと思う。どこまでの作業まで元に戻せるかはアプリケーションによって違って、EXCELだと保存すると元に戻せなくなるので注意。
検索はWORDでもEXCELでもブラウザでもメモ帳でも重宝すると思うので、ショートカットを覚えたいところ。

自動的に一発でやってくれる作業を地道にやらない

自動化できるところは自動化した方が良いのだけど、あれもこれも覚えるのは大変。とはいえ、以下のような状況では自動化に頼ったほうが良いのではと感じる。

  1. 1〜100までの連番を入力
  2. 一杯ある「はてなダイアリー」という文字を「はてダ」に変更
  3. 下に長いWebページのキャプチャ画像を撮る

1.はEXCELフィルハンドルが良いと思う。仮に10000までであっても、関数とか使わずに愚直にフィルハンドルでスクロールして、それを選択してコピペする方が楽で速いと思う。あと、フィルハンドルは曜日の繰り返しとか他の用途でも使えるので、繰り返しっぽいと思ったときはやってみると良いと思う。
2.は置換を使う。これはメモ帳でもWORDでもEXCELでも、大体のアプリケーションであると思う。プルダウンメニューの編集にあることが多い。検索した言葉を別の言葉に置き換えてくれる。
3.はキャプラとかを使う。リンク先の説明の「スクロールで隠れた部分もキャプチャ可能」がその機能。自分でスクロールしてはPrintScreenを撮ってという繰り返しを地道にしたりしないように。

どこにあったか探さなくて済むように工夫する

全てを諦めてGoogleデスクトップでも良いかもしれないけれど、例えばプログラムを起動するときに「スタート」->「すべてのプログラム」でプログラム一覧を表示すると、その時点で目が目的のアプリケーションの場所を探していると思う。bluewind使えとかいう話もあるけれど、そこまでしなくても、よく使うアプリケーションなんて決まっているのだから、タスクバーのクイック起動にアイコンを置くとか工夫した方が良いと思う。要は頻出度の高いものだけでもピックアップして楽にしておくことが大切だと思う。
メールだと常に自分BCCがお勧め(もちろん毎回自分でBCCを入力したりせずにメーラーの設定で自動入力する)。なぜかというと送信済みのボックスから自分の送信メールを探さなくてよくなるから。全て受信箱で管理したほうが、そのメールの返信もすぐに見れて楽になる。Gmailだと自動的にそうなっているけれど。

面倒な文字とかを毎回入力しない

コピペ元となるテキストファイルを作って、いろいろ箇条書きにしておくのも良いけれど、IME辞書に登録するのも有効。自分の場合、「お」でスペースキーを押して変換させると「お疲れ様です。○○です。」と変換されるようになっていたりする。ただ、ブラインドタッチが高速な人は愚直に入力するほうが、頭を使わなくて速かったりするかもしれないけれど。

知ってそうな人に遠慮せずに聞く

最後だけ人間的なこと。プログラマとかが近くにいる職場だったら、上記のようなことはいくらでも知っているので、とにかく聞いて覚えるのが良いと思う。面倒だなとか大変だなとか思うことが、本当に大変なことなのか、自分のやり方が悪いのか、常に考えていて損はないと思う。
結局のところ、「楽するために楽しないこと」が近道と思われる。勿論、ここで言う「楽しない」は非効率な作業に苦しむことではなくて。