お世話になっている国産のソフトウェア

Appleが日本を軽視する理由 – Life with Mac and more.
ここに書かれている、

年賀状印刷や会計処理のような日本特有の事情を踏まえて開発されたものを除けば、我々が日ごろ使っているツールは、ほとんどが日本向けにローカライズされた外国製品ではないでしょうか。

を読んで、そうかなぁなんてぼんやり思った。反論とかのつもりはないけれど、自分のお世話になっている国産ソフトウェアを書いてみる。

先日USで勤務していた人に聞いたらBecky!のシェアあるよということで驚いた。外国でも使われているのかと。当然クライアントメーラなのでGmail的なメリットはないにしても、本当に良く出来たメーラだと思う。今でも愛用している。

SFTPが使えるクライアントとしては一番好きでこれも愛用。利用するときはさっぱり簡潔な画面だけれども、かゆいところに手が届くカスタマイズ性が良い。あと、見た目もきれいだし違和感なく使える。サーバーのファイルを編集していて保存した瞬間に自動アップロードとかできたり、良い感じに機能も多い。

EmFTPと同じような感じで愛用品。Windows環境で使うエディタとしては一番利用する。

無料というのもいいし、簡単なことをサクッとやるときには軽いし便利。

ゲーム音楽をこんなに統一して聴けるプレイヤーは他には今のところ知らない。簡素なインタフェースで必要な機能はあるというところがとても良い。あと、動作もすごく軽い。

これがないともうソフトウェアの起動すらウンザリしそう。コマンドランチャはいっぱいあるのだけれども、普段はコマンド窓しかないのに設定は充実というところで愛用。

フリーソフトをあげだすと、窓の手とかそんなのも出てきそうなのでこの辺で。Macが云々は置いておいて、自分としては日本人作のソフトウェアにもかなり助けられている次第。シェアウェアにしてもフリーウェアにしても、本当にありがたい。

ヴァイオリンは弾く以前に挟む

ヴの字も知らずに始めたヴァイオリンだけれども、妙なところで難しい。それは挟むことだ。
いや、説明しよう。恥ずかしながら演って初めて知ったのだけれども、ヴァイオリンは挟まないと何もできない。何を挟むのかというとヴァイオリンをだ。つまり、肩と顎でヴァイオリンを挟んで固定(ほんとうにがっちり固定するほうがよいのかはまだわからないけれど)しなければ、そもそも左手で弦を押さえることが難しい。これは自分的には予期しなかった障壁だ。ギターなら足におけばそれで終わりなのだから。
そして、この「挟む」が結構難しい。ただ、そうこう言っていたら一生弾けないので、割と頑張ってみたところ、どこで挟むかが重要に思えた。顎と一言に言っても、耳下の頬骨のところから下顎まで場所は様々なのだけれども、顎は頬の側ではなくて口から垂直下の場所(ただし左より)、肩はかなり首に近い場所、という組み合わせが上手くいくように思う。
上記のような挟み込みをすると、やっとヴァイオリニストのような角度でヴァイオリンを構えて、しかも左手でネック(って言うの?ヴァイオリンでも)をささえることなく挟むことができる。
間違いなく度素人なんだけれど、しかし、超絶技巧と同じ構えがどうしたらできるかをやっているうちにこうした回答が導き出される。多分、しばらくはレオニード・コーガン氏(師)の教則映像を参考にするつもり。

トラックバックが届くのだか届かないのだか

先日書いたエントリで404 Blog Not Foundトラックバックを送ったのだけれども反映されていない様子。過去に何度か送ったこともあるけれど、一度も送れていないように思う。ただ、はてなダイアリーからのトラックバックも一杯あるので、こっちの問題なんだろうなとは思う。参照リンク含めるだけではだめだとか。あと単純に人為的なミス(いや意図的か?)で消されているとか。
最近ではスパムフィルターがあるのは当たり前だし、どんなものでも確認して承認後に公開している人も多いと思う。なので、送ったときには成功したのか失敗したのかの判断がつかない。
TrackBack Technical Specificationを見ているとエラーコードの定義とかはないのかなと思った。例えば、「すぐに公開されます」「承認待ちです」「失敗(スパムフィルタを含む)です」とかが解るだけでも、少しはうれしいのにとか思う。
ただ、スパムフィルタにかかったのは承認待ち状態にするだけで消さないとかいう設定の人も当然いるだろうし、仕様として確定するのがむずかしいものなのかなと思う。あと、どういう内容だと失敗してどういう内容だと成功するというのが判別されると、スパムフィルタ定義を調べるスパマのためのプログラムが出来てしまいそうで、それでは元も子もない話になってしまう。
最近、「トラックバックは届かなくて当たり前」という発想に自分がなっているのがなんだか嫌だなと思った。

PHPは一発屋としては最高

いろいろPHPがひどく言われている模様。
404 Blog Not Found:そろそろPHPに関して一言いっとくか
IT戦記 – じゃあ、僕も PHP について一言いっとくまうす
もちろん、物申している方もいる。
odz buffer – PHPに文句を付けている dankogai 氏にひとこと言っておくか
なんというのか、そうなんだけどとしか言いようのないところで皆さん批判するからもっともだし反論する気にもならない。でも、多くの人の意見は「プログラマがプログラムするために使うなら」という前提条件の元で書いているのではないかと思う。個人のホームページにメール送信フォームを設置したい人とかは華麗にスルーなのか?とか思う。
さてさて、PHPでも普通にプログラム書くことはそれなりにできるのだけれども、自分としては一発屋としてのPHPの素晴らしさを強調したい。一発屋というのは単一機能なコンパクトCGIが欲しいときにこれほど便利な言語はないという意味で解釈して欲しい。
たとえば、リクエストされたファイル名とファイル内容を保存するCGIを作るときにPHPだと以下の一行だ。

<?php
file_put_contents($_REQUEST['name'], $_REQUEST['value']);

※上記の例は無謀すぎたのでコピペして利用したりしないでください。追記しました。

「リクエストの値をチェックしろよ」とかはもっともなのだけれども、例を単純にするためにというのと、多分どんな言語でも値をチェックするならもう少し行数いるだろうと思うので。あと、例えば話、自分用に作ったものとかだったらこんなトンデモな仕様でもできてしまうものなので。とりあえず、こんな具合に一発屋CGIとしてなら自分はPHPを素晴らしい言語だと思っている。
なぜ、上記のような無謀な例を出したのかというと、それくらいにPHP自体によって提供されたグローバルな関数が山ほどあって、その関数に頼ると「一発屋CGIはあっという間に完成する」ということの実例で示したかったからだ。本当に関数は山ほどある。
例えば、PHP: 配列関数(array) – Manualの下の方にある関数群を見て欲しい。仮にこれらの関数をArrayオブジェクトのメソッドだとしてとらえたならば、こんなにメソッドがあるのは頭がおかしいのではないかと疑うくらいだろう。なんというのかPHPはこれこそ良い感じなのだと思う。配列をソートしたいなら

<?php
sort($hoge);

連想配列のキーでソートしたいなら

<?php
ksort($hoge);

という、やりたいことをその瞬間に済ますというスタンスでみると素晴らしいのだと思う。
自分はそのようにPHPを理解していたので、PHP5で大規模PHP対策な仕様になったのが残念だったのだけれども、とはいえPHP5を使ったとしても今まで通り気軽なCGIに取り組むことは可能だ。要するに、PHPという言語は「プログラミングしたくない人にお勧めできる言語」ということになるのではないかと思う(もちろんPHP言語開発者の意図・願望は知らない)。
さて、一発屋としてのPHPを押してみたのだけれど、PHP生粋の人たちには、「一発屋PHPなんかじゃなくてMVCフレームワークも一杯あるし、とにかくWebサイトの構築にはPHPは大いに貢献しているではないか!」というような批判を貰いそうだなと感じた。確かにそうだと思う。PHPでWebサイトの構築は明らかに可能だろう。ただし、構築できることとベストな言語であること別問題だ。
特にPHPは負荷に対する取り組みが適当な印象を受ける。例えば、PHPコンパイル済みバイトコードをキャッシュするのに、APCを使うとか、有償でZend使うとか、そういう発想が結構意味不明だったりする。それこそPHP自身が実装して吸収してしまえば良いのにと思うけれど、どうだろうか。
おかしいな、PHP最高という話をするはずだったのに最後に批判的な意見を述べてしまった。いや、便利な言語なんだ、PHPは。苦し紛れにまとめると、バイト数を争わない気軽なワンライナーを使うのだったらPHPは良い言語だよといったところか。

余談だけれどもDanさんの書いていた例は普通はforeachを使うのが一般的だと思う。以下のように。

<p>以下の環境変数が設定されています:</p>
<pre>
<?php
foreach($_SERVER as $k => $v) {
echo htmlspecialchars("$k=$v\n");
}
?>
</pre>

かなりの余談だ。どっちでも良い話。
id:odzさんの意見を尊重してhtmlspecialcharsを入れています。

[追記]
PHP について (2) – セキュリティについての考え
トラックバックでツッコミを頂いた。そして安全性に欠ける例えを様々な知識レベルの人が閲覧するWebで公開しているのもよくないことだなと反省したので、注釈を追加しておいた。
ご指摘ありがとうございました。

PHPのelseifとelse ifの違い

2018/12/28追記 この記事は2007年に書いたものです。現在は PSR-2: Coding Style Guide – PHP-FIG に従うことが多く elseif を利用するのが一般的だと思います。

Javaの次にPHPを学んだせいというか、最近PHPのソースを見たときにelseifがあって違和感に感じることがあった。

PHPでは、(単語二つで)’else if’と書くこともできます。 動作は(一単語の) ‘elseif’と同じです。文法的な意味はやや異なっています。 (あなたが C 言語に詳しいとすると、C 言語のそれと同じ動作です。) しかし、最終的な両者の動作は全く同じです。

PHP: elseif – Manual

となっているようにどちらでもちゃんと動く。挙動は同じと書いてあるので疑うことはないにしても「文法的な意味はやや異なっています」と言われると気になる。
そもそも何がどう違うのかというと、

C/C++ でよく見かける else if (condition) は言語としての仕様ではなく、個別の if then else 文が入れ子になってあたかもひとつの構文であるかのようにコーディングされているだけのものである。しかし、これは else-if がコンパイル時に効率的に処理されるのでない限り C/C++ では必要とされないことを意味している。一般に elseif は論理的には if…else の入れ子よりも単純であり、両方を用意している PHP などの言語では elseif は else if よりも効率的に処理される。

制御構造 – Wikipedia

という話で要するに

if ($hoge == 'hoge') {
} else
    if ($hoge == 'hogehoge') {
    } else
        if ($hoge == 'hogehogehoge') {
        }

ということをやっているだけで、else ifではなくてif elseの入れ子だよということだ。意識したことなかったけれど、確かに言われてみたらそうとも取れるか。zend_language_parser.cとかもチラッと見てみたけれど、ELSE_IFとして認識するような箇所はなくてIFかELSEかELSEIFかしかない。
実際のコーディング上の一般論だと何が良いのかなと思ってPEARとZendFreamworkのコーディング規約を参照してみると、PEAR :: Manual :: 制御構造ではelseifしか記述になく、Zend Framework A.4.6.1. If / Else / Elseifでは逆に

“elseif” を使用することは可能ですが、推奨されません。代わりに “else if” を使用してください。

なんてことが書いてある。実際にソースをgrepして検索してみたところPEARでは確かにelseifばかりが使われていて、ZendFrameworkでは両方が同じくらいの量が見つかった。
自分の今までみてきた日本人の書いたコードだと圧倒的にelse ifの方が多かったけれど、世の中的にはどうだろうと気になったので人力検索で質問してみた。

[追記]

elseifelse ifケースバイケース
67人66人67人

世の中的にはどうでもよいみたい。質問の仕方があまりにシンプルでよくわからずに答えた人がいるかもしれないけれど、それにしても「ケースバイケース」な人が結構いるもんだ。編集するファイルのコーディングにあわせるとか、規約に準ずるとかならわかるのだけれど、気分で使い分けているなら、どういうときの方がどっちが見やすいとかそういう論はあるのだろうか。

ブルースクリーンな一日


メインマシンのdynabook SX/190NRがついに真っ青になった。PC暦が1年くらいの人だとこの時点でこの世の終わりと思えるかもしれないけれど、一応プログラマとかやっている身なのでいろいろ頑張ってみた。
まずブルースクリーンに書いてある内容は、「エラーが見っかったからPC壊れないようにWindows止めたよ。初めてこのエラー画面みたんだったら、再起動してみて。それでもこの画面でるんだったら、下に書いた手順にしたがってね」みたいな感じで始まる。
なので、とりあえずは再起動をしてみたわけだが、残念ながら全く同じ画面だったので、ブルースクリーンを読み進めてみる。だらだらと書いてあるけれど、「ハードとかソフトを新しくちゃんと入れたんだったら、製造元に聞いてみれば?それでも問題あるんだったらセーフモードに入って消しちゃいなよ」という感じだ。
確かに、こういう場合はセーフモードで入れるかどうかが分かれ目な気がする。ということで、F8押しながら起動してセーフモードにログインしてみたら、ちゃんとWindowsが起動できた。とりあえず、この時点でファイルバックアップはとったけれど、Windowsの再インストールはしたくなかったので、原因究明をしてみることにした。
手始めにブルースクリーンで表示されていた「BAD_POOL_HEADER」が何であるか検索してみたところ、きままな日記帳: デバイスドライバ屋にとってのXP SP2というエントリに出会って読んでみるとなるほどな感じ。ただ、自分の場合はハードを追加していないので、何かしらのソフトがエラーになっているという感じだと考えた。
とりあえずデバイスマネージャを見てみたけれど、!になっているものは一つもなかったので、次にイベントビューアのシステムログを見てみたところ、それっぽいエラーは見当たらない。不良ブロックでdiskがエラーになっているのを見つけたので、chkdsk c: /F とかお決まりをやって修復してみたけれど、これは全く別問題だった様子。相変わらずブルースクリーンなので、面倒だけど、MEMORY.DMPファイルを見てみることにした。
MEMORY.DMPはブルースクリーンの最後にも書かれているけれど、その名の通りメモリ状態のダンプファイル。ただ、これが残念ながら単純なテキストファイルではなくバイナリなので、仕方なくDebugging Tools for Windowsを落としてきて読み込んでみた。
すると結構意外なファイルが原因っぽいことが判明した。

bafbba3c 8054d941 000000c2 00000007 00000cd4 nt!KeBugCheckEx+0x1b
bafbba8c a7ac5fc9 88c6c004 00000000 bafbbad0 nt!ExFreePool+0x697
bafbba9c a7ababfa 88c6c004 892e5a64 88c6c004 symidsco+0xffc9
bafbbad0 a7aba9e6 8922aa64 bafbbb48 bafbbb44 symidsco+0x4bfa
bafbbb28 a7ab8329 bafbbb48 bafbbb44 892e5a28 symidsco+0x49e6
bafbbb54 a7ab73b2 00000000 bafbbb7c 892e5a28 symidsco+0x2329
bafbbb74 a7ac5bb6 89643f00 89278148 00010000 symidsco+0x13b2
bafbbbac a8f67652 bafbbbc0 bafbbbf8 bafbbc5e symidsco+0xfbb6
bafbbbd4 a8f677f1 a7addfca bafbbc7c a7ac118b SYMIDS!SymIDSCoInterface_RegisterRequest+0x1222
bafbbbe0 a7ac118b bafbbbf8 89600128 e267540a SYMIDS!RegisterRequest+0x91
bafbbc7c 805a5f27 89600128 89137000 00000000 symidsco+0xb18b
bafbbd4c 805a61fc 00000858 00000001 00000000 nt!IoWMIOpenBlock+0xefd
bafbbd74 804e626b 00000858 00000000 89306518 nt!IoWMIOpenBlock+0x11d2
bafbbdac 8057f0f1 a7c30944 00000000 00000000 nt!ExQueueWorkItem+0x104
bafbbddc 804fa27a 804e6196 80000001 00000000 nt!PsCreateSystemThread+0x70
00000000 00000000 00000000 00000000 00000000 nt!KeInitializeTimer+0x107

symidsco?ってなことでsymidscoを調べてみると

start    end        module name
a7ab6000 a7ae7000   symidsco   (no symbols)
Loaded symbol image file: symidsco.sys
Image path: \??\C:\PROGRA~1\COMMON~1\SYMANT~1\SymcData\IDS-DI~1070507.001\symidsco.sys
Image name: symidsco.sys
Timestamp:        Sat Jan 13 08:29:35 2007 (45A819DF)
CheckSum:         00032D38
ImageSize:        00031000
File version:     7.2.1.1
Product version:  7.2.1.0
File flags:       0 (Mask 4F)
File OS:          40000 NT Base
File type:        0.0 Unknown
File date:        00000000.00000000
Translations:     0409.04b0
CompanyName:      Symantec Corporation
ProductName:      Symantec Intrusion Detection
ProductVersion:   7.2
FileVersion:      7.2.1.1
FileDescription:  IDS Core Driver
LegalCopyright:   Copyright (c) 2006-2007 Symantec Corporation
LegalTrademarks:  Copyright (c) 2006-2007 Symantec Corporation

ということで、犯人はAntiVirusなのか?ということに。
そこで、セーフモードでAntiVirusのアンインストールを試みてみたら、ご丁寧に「セーフモードではアンインストールできません」とか言われた。何これ?八方塞?みたいな感じに5秒くらいなったけれど、どうせこのままだとWindows再インストールの道しかないので、symidsco.sysを別の場所に移動して読み込めないように嫌がらせをしてみた。
その後に再起動するとセーフモードでなくてもWindowsを起動することが出来るようになった。当然、AntiVirusは変なエラーダイアログを出していたけれど、即刻アンインストールして入れなおしたら、ちゃんと復活した。
結局のところは原因不明。とはいえ、元に戻ったので、めでたしめでたし。
今回いろいろ調べている最中に、Daemon Toolsをアンインストールしてもsptd.sys消さずにずっと起動するたびにエラってるとか、VMWare Serverをアンインストールしてもvmnet.sysとかvmnetadapter.sysとかは消さずに置いてきぼりにしてるとか、そういう関係のないこともわかった。

[追記]
後日、ハードディスクの物理エラーによってハードディスクを交換することになったので、たまたまディスクアクセスするNortonがエラーになってしまっていただけかもしれない。

window.screenがなかったらJavaを呼び出すGoogle Analytics

Google AnalyticsのJSソースを読んでいて思った。

if (self.screen) {
sr=screen.width+"x"+screen.height;
sc=screen.colorDepth+"-bit";
} else if (self.java) {
var j=java.awt.Toolkit.getDefaultToolkit();
var s=j.getScreenSize();
sr=s.width+"x"+s.height;
}

正確なレポートを目指す上での実装なんだろうけれど、クライアントはJavaの呼び出しで重くなってるんだろうなとか思う。最近の主要なブラウザでscreen.widthとかが取れないことはなさそうだけれども。

ヴァイオリンを始める

会社の同僚からサイレントヴァイオリンを借りることができたので、のんきに練習しようと思う。

ヴァイオリンのヴの字も知らないので、どうやって覚えようかと思ったけれど、ギターを覚えたときのように超絶技巧な人の真似をして覚えることにした。
ということでこれを教則ビデオにしてみる。
http://youtube.com/watch?v=Ovnky2hwgWM
レオニード・コーガンという人らしい。最初はやたらと遠いのだけれど、最後の方は後ろからとかいろいろな角度から映してくれているので、非常に教則としてはよい素材だ。