1/3のピアノが弾きたい純情な感情

2009/11/16 17:59:00

ふぅ

 こしばらく、ピアノを弾いていないんですよ。実家にいるときは、毎週ピアノを弾く機会がありました。現在は、ひとり暮らしたのめ「ピアノ」から距離を置いている生活が続いています。しかし突然、とてつもなく「ピアノを弾きたい衝動」に駆られることがあります。最近は、実家に帰る理由が、両親に会うことよりもピアノを弾くことだったり……はさすがにしませんけども(笑)。

 在、借りている部屋の契約条件は、「ペット」「石油ストーブ」「ピアノ」が禁止となっています。そもそもピアノを置けるようなスペースなんか余っていないので、「ピアノ」を禁止されていてもまったく問題ないのです。しかし、無性にピアノが弾きたい感情をどう解消するのか? その対応に頭を悩ませておりました。

ePiano.jp

 ンターネット上でピアノを弾くなら、「ePiano.jp」というサービスがあります。約1年前に始まったサービスです。第一印象は、正直にいうと「せまっ!」でした。本物のピアノは88個の鍵盤あります。ePiano上では「左手が活躍するスペース」が十分に確保されていません。掲示板の要望や投稿作品のコメントを見ても、「せめてあと1オクターブ欲しい」という声がちらほら見受けられます。

 から知ったのですが、DTM(DeskTop Music)の世界では、ePiano程の鍵盤数のMIDIキーボードで曲の打ち込みをしているそうです。そうか! 確かにデジタルな曲の打ち込みならば、リアルタイムで演奏する必要はありません。だから、オクターブを上げ下げする機能を使用することで、鍵盤の数を必要最低限に抑えているんですね。

Play

 練習はこちら。

 際に触ってみると、「けっこういいWebサービスかもしれない」と思えてきました。何より、トラックを分けて別々に録音して重ねられるし、練習機能も付いている。操作に慣れてしまえば、かなり遊べそうなPianoですね。調子にのってもう1曲弾いてみました。左手なしですが、「ジュピター」の出だし部分です。

 練習はこちら。

There is XML Data.

xml

 れはまったくの偶然でした。何の気なしに「作者のブログ」を覗いていたところ、驚くべき仰天事実が。なんと! 曲のデータは「XML」で保存されているとのこと。さらに、このXMLデータを使用して、何かマッシュアップを行って欲しいそうです。さすが「Web2.0」時代のサービスですね。

Silverlightで開発スタート

 かし、わたしは「XMLで音データが保存されていた」事実よりも、「ePianoの鍵盤が37鍵しか存在しない」事実の方がどうしても気になっていました。そこで「Silverlight」という技術を使って、88鍵のPianoを作ることにしました。

 Silverlightは「XAML」という定義ファイルに、「XML」を使用しています。また、わたし自身は「.NET」技術者ですし、Silverlightで開発する環境も整っています。あとはやるだけ。年内に完成できるかは微妙なところです。しかし、期限を切らないと「モノゴト」はなかなか前に進まないので、とにかくやってみます。

『TypePadクエスト』第3話:カスタマイズですね。わかります。

2009/10/27 19:20:00

パッケージ製品のカスタマイズ

 もそもソフトウェアにおける「パッケージ製品」ってなんでしょうか? なかなか一言で説明するのは難しい概念ですね。もしも就活中の学生さんに質問されたとしたら、わたしは以下のように説明します。

 「紳士服売り場でハンガーにかかっている状態のスーツ」のこと。

 えば、人間の「からだ」にはそれぞれ個性があるから、ハンガーに掛かったままの状態だと、すそが長かったり、おなか周りが苦しかったりします。そんなときは、すそを詰めたり、アジャスタつきのパンツをご提案します。そういう「お客様の事情に製品を合わせる」のが僕らのお仕事です。

カスタマイズの量を最小限にしてみたら

 て、パッケージ製品のカスタマイズには、「まったく新規に開発する」場合と違って、注意すべき重要なポイントが存在します。それは、「パッケージのバージョンアップを考慮してカスタマイズする」ということです。以下に具体例を記します。

 えば、お客様の「ビジネスロジック」を実現させるために、以下の3つの方法があったとします。

方法1 ファイル「AAA」「BBB」「CCC」の該当箇所を数行修正して実現する
方法2 ファイル「AAA」だけで、100行程度修正して実現する
方法3 ファイル「DDD」を新規に追加し、200行で実現する

 3つの方法の中で、最小限の労力で実現できるのは、もちろん「方法1」です。しかし1には、大きな落とし穴が待っているのです。それは、「パッケージのバージョンアップ」のお話が怖くなるのです。

ありがたいはずなのに……

 ッケージのバージョンアップは、開発会社にとっては、とってもありがたいお話です。しかし「方法1」のように、「AAA」「BBB」「CCC」の3ファイルに渡って修正していると、パッケージのバージョンアップによって、3ファイルのどれかに修正が入るかもしれません。

 に、「CCC」ファイルに修正が入ったとします。すると、「お客様のビジネスロジックを実現させるために変更したコード」なのか、「パージョンアップによって変更したコード」なのか複合的にロジックが混ざってしまい、わけが分からなくなってしまうのです。昔の自分による「安易な判断」を猛烈に反省し、ひたすらコードと格闘する夜が続きます。そうです。ここでは新規にファイルを追加して200行で実現する「方法3」を採用し、パッケージ標準ファイルへの変更を避けるべきだったのです。

実践

 単なサンプルを叩き台にして、実際にカスタマイズしてみます。お客様の要望は以下の通りです。

 「パンチボタンを押したら、ジャブに続いて昇龍拳を表示してほしい」

 ッケージ標準のファイルの内容は以下の通りです。

■common.js
1
2
3
4
function Punch()
{
    alert(
"ジャブ");
}

■Original.aspx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ Page Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml" >
<
head runat="server">
    <title>パンチ</title>
    <script type="text/javascript" src="./js/common.js"></script>
</
head>
<
body>
    <form id="form1" runat="server">
    <div>
        <input id="btn01" runat="server" type="button" value="パンチ" onclick="Punch();" />
    </div>
    </form>
</
body>
</
html>

 の状態からカスタマイズしていきます。

 客様に言われた通りにただ実装するだけなら、「common.js」の内容を修正すればOKです。しかし「common.js」は名前からして、他の「aspx」ファイルからも利用されている可能性が高いです。

 を恐れているかというと、「Original.aspx」では「パンチボタン」から呼び出されていましたが、他の「aspx」では「ジャブボタン」から呼び出されているかもしれません。単純に「Punch」メソッドの内容を書き換えてしまうと、「ジャブボタン」を押した場合にも、「昇龍拳」が表示されてしまいます。

■common.js(危険バージョン)
1
2
3
4
5
function Punch()
{
    alert(
"ジャブ");
    alert(
"昇龍拳");  // これは危ない
}

 こで「common.js」は変更せずに、「aspx」ファイルにカスタマイズを加えます。具体的には以下のようにします。

■Override1.aspx(最初のカスタマイズ)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<%@ Page Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml" >
<
head runat="server">
    <title>パンチ</title>
    <script type="text/javascript" src="./js/common.js"></script>
    <script type="text/javascript">
       
       
function Punch()
        {
            alert(
"ジャブ");
            alert(
"昇龍拳");
        }
       
   
</script>
</
head>
<
body>
    <form id="form1" runat="server">
    <div>
        <input id="btn01" runat="server" type="button" value="パンチ" onclick="Punch();" />
    </div>
    </form>
</
body>
</
html>

 スタマイズ対象の「aspx」ファイルに、改めて「Punch」メソッドを定義し直しました。

 こで重要なポイントが2つあります。

 1つ目は、「Punch」メソッドの再定義は「common.js」の後に追加する必要があるということです。JavaScriptのメソッドの定義は、後出しが勝ちますので、「common.js」よりも先に定義してしまうと、「common.js」の定義で上書きされて「ジャブ」のみの動作になってしまいます。

カスタマイズの真意を問う

 2つ目のポイントは、お客様から依頼された「カスタマイズの真意」を確認しておくことです。つまり「お客様はなぜ、昇龍拳を追加したいのだろうか」という意識をもって、仕様を詰めていく必要があるということです。例えば今回のカスタマイズの場合は、以下のような可能性が考えられます。

● 可能性1 「ジャブ」だけの攻撃じゃ寂しいから、「昇龍拳」も追加しておくか
● 可能性2 やはり攻撃の最後は「昇龍拳」でフィニッシュしたいね

 しもお客様の真意が後者だったと確認できた場合、「Override1.aspx」のカスタマイズでは不十分です。それでは一体、何が足りないのでしょうか? 答えは「パッケージのバージョンアップを考慮していない」ことです。

バージョンアップしたら不具合発生

 客様の依頼によってパッケージのバージョンアップを行いました。バージョンのアップに伴い「common.js」の内容にも変更があったようです。

■common.js(バージョンアップ後)
1
2
3
4
5
6
7
function Punch()
{
    alert(
"ジャブ");
    alert(
"ストレート");
    alert(
"フック");
    alert(
"アッパー");
}

 の状態で「Override1.aspx」でパンチボタンを押した場合、「ジャブ」「昇龍拳」が表示されます。バージョンアップ前と変わりません。しかしお客様の認識では、「ジャブ」「ストレート」「フック」「アッパー」「昇龍拳」が表示されると思っています。そのため、現在のカスタマイズ状態では不具合が発生していると指摘されます。

ベースを呼び出す

 「Ovdrride1.aspx」のカスタマイズは失敗でした。それでは、「バージョンアップ前」と「バージョンアップ後」の両方で、「お客様の認識通りに動くカスタマイズ」をするには、一体どのようにすれば良いのでしょうか。具体的には、以下のように修正します。

■Override2.aspx(バージョンアップ前・後対応バージョン)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<%@ Page Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml" >
<
head runat="server">
    <title>パンチ</title>
    <script type="text/javascript" src="./js/common.js"></script>
    <script type="text/javascript">
       
       
var basePunch = Punch;
       
   
</script>
    <script type="text/javascript">
       
       
function Punch()
        {
            basePunch();
            alert(
"昇龍拳");
        }
       
   
</script>
</
head>
<
body>
    <form id="form1" runat="server">
    <div>
        <input id="btn01" runat="server" type="button" value="パンチ" onclick="Punch();" />
    </div>
    </form>
</
body>
</
html>

 ずは「basePunch」にパッケージ標準の「Punch」メソッドを保存しておきます。そして、新たに定義した「Punch」メソッド内で、「basePunch」を呼び出します。

 イントは、「scriptタグ」を2つに分割し、「basePunch」への保存と、新しい「Punch」の定義を分けることです。もしも同じscriptタグ内に書いてしまうと、再帰呼出になり「スタックオーバーフロー」が発生します。

お客様の真の要望を満たす

 「Override2.aspx」の修正によって、「ジャブ」「ストレート」「フック」「アッパー」「昇龍拳」が表示されるようになりました。この状態にカスタマイズできれば、バージョンアップ前の「common.js」の状態でも、「ジャブ」「昇龍拳」が表示され、お客様の要望をきちんと満たしています。

 回のカスタマイズの例では、「Punch」メソッド自体の内容が数行と少なく、「basePunch」に保存しておくメリットがあまり感じられませんでした。しかし、「jQuery」や「prototype.js」等のライブラリを使用していて、ライブラリの動作を変えたい場合があったとします。ライブラリの内容を、直接変更してしまうのは大変危険です。その場合は、「basePunch」のように「標準のメソッド」を保存しておく方法によって、大きなメリットが生まれてきます。

ありがとうございました

 て、今回でついに「TypePadクエスト」が終了です。「TypePadの自動修正」に対抗する目的で始まったこの企画。色々な試みをさせていただきました。第1話は「お馬鹿アプリ」、第2話は「Youtube + コナミコマンド」。そして今回は「TypePadの自動修正に対抗する」……。

 もそも「TypePadの自動修正」が発生する直接的な原因は「FireFox」でした。「FireFox」を使用しTypePadエディタ上で、画面スクロールを発生させることによって「半角スペースの統合」が発生します。半角スペースの数が狂うことによって、ソースコードが崩れるのです。しかし、記事の確認はエンジニアライフの運営上、必要不可欠である工程です。そこで、何とか解決する手段はないものかと調査を行い、今回の実装となりました。ソースコードは、うまく表示されているでしょうか?

『TypePadクエスト』第2話:逆転脱出

2009/10/06 19:25:50

はじめての軟禁

 「サーバルーム」。

 それは、侵入することがとても難しい部屋。

 しかし、そこから脱出することは、侵入すること以上に困難である部屋。

 不幸にも閉じ込められた「あなた」は、待ち受けている「運命のいたずら」の数々に、果たして耐えられるのか?

●○●

 「システムの不具合」によって怒り狂う「情シス担当者」が、あなたを追いつめる。

 必要以上に冷やされた室温によって、あなたの体力が徐々に奪われていく。

 そしてあらたなる敵、「尿意」が登場。

 冷静な判断の継続がさらに困難に。

 ネットワークセキュリティも最高レベル。

 インターネットから切り離された端末しか存在しない。

 あなたのうろ覚えの知識が次々と「無力化」する。

 ここには当然「Visual Studio」は存在しない。

 使用できる武器はただ1つ。「メモ帳」のみ。

 果たして、あなたは無事に生きて脱出することはできるのか?

●○●

脱出系

 さんこんにちわ。ゲームの中でも特に、「脱出系ゲーム」にハマっている昨今です。あの「クリムゾンルーム」がなんと、Nintendo DSで出ていることを最近知りました! 早速Amazonで注文です。

 回は、ある意味脱出系ともいえる「サーバルーム」から、実際に「奇跡の生還」を果たした技術者の実体験をお送りします。

 はどうぞ。

直さないと出られない

 ーゲットは、ASP.NET2.0のWebアプリ。

 わたしの仲間が作ったアプリだ。

 しかし、こいつがうまく動かなかったせいで、予備知識の全くないわたしが閉じ込められたのだ。

 自らの不幸をいくら嘆いてみたところで、何の解決にも繋がらない。

 とりあえず、現状を冷静に分析してみることにする。

 それが「生きることへの希望」を捨てていない決意の行動でもあるのだから。

 ……どうやら言語はバイリンガル。C#とVB.NETの両方を使用している。

 コードビハインド有無は、ほぼ8割コードビハインドだ。

 運が悪いことに、「Webプロジェクト」で作られているようだ。

 「Webサイト」で作られていれば、「メモ帳」だけで十分に戦えたものを……。

修正個所を特定する

 たしは、できる限りの情報を集めた。

 何しろ、こちらの武器は「メモ帳」しかないのだ。

 どんな些細なことでも、解決の糸口になる可能性はある。

 そして、ついにわたしは、修正しなければならない箇所をつきとめた。

 しかし、それは、わたしを喜ばせ、かつ、失意のどん底に叩き落とした。

 なんと修正個所は、「コードビハインドした中」にあったのだ。

 「Webプロジェクト」の場合、コードビハインドしたコードはコンパイルされ、「DLLファイル」に変化する。

 ところが、「DLLファイル」になったが最後。メモ帳ではもはや修正することができない。

 「人生終わった」。

 もはや、自らの運命を恨む気力すらなくなっていた。

 30分くらいが既に経っただろうか。

 ただただ、端末のモニターを、目の前に広がる風景としてながめていた。

 「サーバルーム」の異様な寒さの中、わたしの思考回路は「完全停止」していた。

 さらに10分ほど経過したところで、それは突然やってきた。

 何かにたとえるならば、「天からの助け」が頭の中に舞い降りてきたかのように、とあるアイデアを閃いてしまったのだ。

デリゲートから抜く

 たしは生き返った。

 もう一度修正箇所をよく確認してみた。

 どうやら修正個所は「デリゲートに登録されたメソッドのみ」で構成されている。

 しめた!

 デリゲートは通常、メソッドを登録して使うのものだが、逆に言えば、登録してあったメソッドを削除することも当然可能なのである。

 修正対象であるメソッドの名前を「AAA」と仮定して、よくよく考えてみる。

 確かに、DLL化した「AAA」メソッドは、もはやメモ帳では修正できない。

 しかし、「AAA」メソッドはデリゲートに登録され、そのデリゲートを呼ぶことで初めて動作する。

 その「AAA」メソッドをデリゲートから抜いて、新たに定義した「BBB」メソッドに入れ替えれば、動作上は「AAA」メソッドの内容を書き換えたことと同じになる。

 これで形勢逆転だ!

生きる

 細胞が再び活発に動き始めた。

 膀胱は今にも破裂しそうだが、目指すゴールまで突っ走るしかない。

 わたしは一心不乱に「ASPXファイル」を編集し、上書き保存を実行した。

 ついに、「メモ帳」だけでWebアプリの不具合は修正されたのだ。

 ようやく「サーバルーム」の重い扉が開く瞬間がやってきた。

 ありがとうデリゲート。あなたのお陰で、生きて帰れます。

 「サーバールーム」から出た瞬間、わたしは生温かい空気に包まれた。

 脱出できた喜びを、まさか部屋の温度差で実感することになろうとは……。

 この日起こった全ての出来事は、一生忘れることのできない「記憶」として深く体に刻み込まれた。

 その後、あの「サーバールーム」がある会社の前を、たまたま通る機会があった。

 わたしを閉じ込めた担当者は、まだ在籍しているのだろうか?

 体に刻み込まれた「生温かい空気」の記憶によって、涙が頬を流れた週末であった。

最後に

 のドラマはフィクションであり、実在の人物・団体等とは一切関係がありません、と言いたいところです(苦笑)。

 回のお話は、技術的に見ると「サーバサイド」のお話でした。実際に修正したサンプルコードを出したところで、大して興味をもってもらえそうにないですし、ソースコードのカラーリングは約2日くらい時間が掛かりそうなので、今回の掲載は無しです。また、別の機会があれば掲載したいと思います。

 回、TypePadクエスト最終話は、「クライアントサイド」のお話になります。

『TypePadクエスト』第1話:CSS Spriteの衝撃

2009/09/24 20:33:47

CSS Spriteの衝撃

Yahoo!

Amazon

Google

 、これは…すごい!。アクセス数が飛びぬけているサイトでは、もはや常識のテクニックなんでしょうか。

CSS Spriteとは?

 CSS Spriteとは、ページ内で使う背景画像を1枚の大きな画像ファイルにまとめ、CSSを使って画像の表示位置をコントロールするテクニックのことをいいます。普通の画像を使ったサイトでは、画像1枚につき1HTTPリクエストが発行され、画像の数だけWebサーバに負担が掛かります。しかし「CSS Sprite」を使用すれば、画像1枚分の1HTTPリクエストで済むため、大幅な通信コストの削減になります。

 た、一度取得した画像は、Webブラウザのキャッシュに保存されるため、その後同じ画像が出てきた場合には、Webブラウザのキャッシュから画像が読み込まれます。Webブラウザのキャッシュ画像の利用によって、ますますWebサーバの負担が軽減されます。

CSS Spriteを実生活に置き換える

 がお得なのか? 我々にはなかなか実感しにくいので、「CSS Sprite」を実生活に置き換えてみます。だいたい以下のような感じでしょうか。

・太郎君はお母さんに言われて、近所のスーパーにマグロの切り身を買いに行きました。

・太郎君が家に戻ってくると、お母さんは言いました。「醤油があと少ししかないから、醤油を買ってきてね」。

・太郎君は再びスーパーへ行くことになりました。

・太郎君が醤油を買って家に戻ってくると、お母さんは言いました。「わさびがもうないから買ってきてね」。

・太郎君はまたまた、スーパーに行くことになりました。太郎君は思いました。「こんなことなら、冷蔵庫の中を確かめてから、買い物メモを持たせてくれればいいのに。いくら近所とは言え、何回もスーパーに行くのは面倒くさい!たった1つの商品を買うのに、また夕方の混雑したレジに並ぶのか…」。

実装してみる

 て、「CSS Sprite」の概念は頭で分かっても、実際にやってみないことには真に理解したことにはなりません。まずは身近な例として、エンジニアライフのプロフィール画像を「CSS Sprite」してみます。当コラムのプロフィール画像は「もみじ」ですね。

 装するにあたり、クロスブラウザの工数は無視できないので、ブラウザのシェア上位1位と2位で動けば良しとします。つまりIEとFireFoxを対象に作ります。

 ロフィール画像をまず4分割し、それを再びくっつけて表示します。4つの画像を新規に作っていない点に注目してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<table id="tbl01" border="0" cellspacing="0" cellpadding="0" style="background-color: #ff0000;">
<tr>
<td>
<div title="コンニャク" style="height: 50px; width: 70px; background: url(http://el.jibun.atmarkit.co.jp/images/profile_hayashi.jpg) -0px -0px no-repeat;">
</div>
</td>
<td>
<div title="コンニャク" style="height: 50px; width: 70px; background: url(http://el.jibun.atmarkit.co.jp/images/profile_hayashi.jpg) -70px -0px no-repeat;">
</div>
</td>
</tr>
<tr>
<td>
<div title="コンニャク" style="height: 50px; width: 70px; background: url(http://el.jibun.atmarkit.co.jp/images/profile_hayashi.jpg) -0px -50px no-repeat;">
</div>
</td>
<td>
<div title="コンニャク" style="height: 50px; width: 70px; background: url(http://el.jibun.atmarkit.co.jp/images/profile_hayashi.jpg) -70px -50px no-repeat;">
</div>
</td>
</tr>
</
table>

 のコードはVisual Studio上で書いたものですが、Visual Studioさんが勝手にXHTMLをフォーマットするので無駄に行数が増えてます。今回は、「CSS Sprite」の分かりやすいサンプルとして「お馬鹿アプリ」に仕上げました。

必殺?斬鉄剣!!

 んにちは。お昼のニュースです。本日未明、XML乱舞は「CSS Sprite向けお馬鹿アプリ」を発表しました。では、会場のパシフィコ横浜から中継です。

あれ?

最後に

 回は「TypePadの自動修正に対抗する」という内容にはまったくなっていませんでした。しかしです。この「CSS Sprite」によって、結果的には「ある扉を開くキー」を手に入れたことになるのでした。TypePad攻略まであと2話……。


インサイダー取引になってしまいます

2009/09/15 18:51:00

インサイダー取引になってしまいます

 式についてはさっぱり知識がありませんが、かなりドキッとする言葉でした。詳しい話を聞くとその会社では、前もって「株式売買申請書」というWeb申請を出さないと、自社株を売却できないルールになっているそうです。そこで現在は、「売却希望日」に「過去日付」を入力してWeb申請できてしまうから、システムでチェックを入れてほしいという要望でした。

JavaScriptでチェックする

 れなら、サーバー側にPOSTする前に、クライアント側でJavaScriptを使ってチェックすればいいですね。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<script type="text/javascript">

function $(id)
    {
       
return document.getElementById(id);
    }

   
function Apply()
    {
       
if(!$("BuyDate").value.match(/^\d{4}\/\d{2}\/\d{2}$/))
        {
            alert(
"売却希望日の形式が正しくありません。");
            $(
"BuyDate").focus();
            
return;
        }
       
       
var buydate = new Date($("BuyDate").value);
       
var today = new Date();
       
       
if (buydate.getTime() < today.getTime())
        {
            alert(
"申請日より過去の売却希望日は許可されていません。");
            $(
"BuyDate").focus();
            
return;
        }

        document.forms[0].submit();
    }

</script>

 ころがです。なぜか「申請日当日の売買希望日」がエラーになってしまいます。「申請日より過去日付のみエラーにする」という実装でOKだったのですが、どうやらうまく動いていません。なぜ22行目に処理が入ってくるのか、机上デバッグでは分かりませんでした。

時刻はいらない

 うです。今回の現象は、日付型には時刻が入っていることを忘れた為に、発生していました。具体的には、変数buydateには「2009/09/09 00:00:00」が、変数todayには「2009/09/09 14:17:50」が入っていました。なるほど~。確かに「buydate < today」なので、当日もエラーで判定されることには納得できました。

現在日付で00:00:00

 由が分かったところで修正方法を考えてみると、時刻の部分で不等式が狂っているのだから、時刻がなくなればいい。つまり「現在日付で00:00:00」が取得できればOKということになります

 ずは、ググってみました。同じことを過去にやった人がいるはずです。すると、さまざまな実装方法が見つかったのですが、だいたい4パターンで書かれていることに気がつきました。それがさらに大きく2つの派閥に分かれます

1行で書くよ派

 (1)newで頑張る

1
2
// newで頑張る
var today = new Date( new Date().getFullYear(), new Date().getMonth(), new Date().getDate() );

 なり頑張ってます。こんなに同じオブジェクトを繰り返しnewしなければならないなら、一度変数に格納したいところです。作者の「1行への執念」を感じました。

 (2)年月日の部分を文字列にして短く

1
2
// 年月日の部分を文字列にして短く
var today = new Date( new Date().toDateString() );

 ちらは、とてもシンプルです。文字数も少なく、ぱっと全体を把握できる点がいい感じです。

2行で書くよ派

 (3)きっちり個別指定

1
2
3
// きっちり個別指定
var today = new Date();
today =
new Date( today.getFullYear(), today.getMonth(), today.getDate() );

 れは、最初に出てきた(1)の変数使用バージョンです。一番件数が多かったです。ちなみにDateのコンストラクタ内では、getMonth()に「+1」する必要はありません。getMonth()は「0~11」を返すので、文字列にして表示する場合は「+1」する必要があるのですが、そのパターンをまねて「+1」してしまい間違っている例がありました。

 (4)後で時間を0にする

1
2
3
// 後で時間を0にする
var today = new Date();
today.setHours( 0, 0, 0, 0 ); 
// 時間,分,秒,ミリ秒を0にする

 かりやすい。頭の中で考えたフローをそのままコードに落としたような実装です。後から誰が読んでも理解できる点が好印象です。

で、結局どれだい?

 局(2)を採用しました。(※実際は以下のように単純なHTMLではなく、もっと複雑なASPXファイルで実装されています。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml">
<
head>
<title>株式売買申請書</title>

<script type="text/javascript">

function $(id)
        {
            
return document.getElementById(id);
        }

       
function Apply()
        {
            
if (!$("BuyDate").value.match(/^\d{4}\/\d{2}\/\d{2}$/))
            {
                alert(
"売却希望日の形式が正しくありません。");
                $(
"BuyDate").focus();
               
return;
            }

            
var buydate = new Date($("BuyDate").value);
            
var today = new Date(new Date().toDateString());

            
if (buydate.getTime() < today.getTime())
            {
                alert(
"申請日より過去の売却希望日は許可されていません。");
                $(
"BuyDate").focus();
               
return;
            }

            document.forms[0].submit();
        }
   
   
</script>

</
head>
<
body>
<form id="form1" runat="server">
<div>
<input id="BuyDate" type="text" style="width: 70px;" />
<hr />
<input id="btnApply" type="button" value="申請" onclick="Apply();" />
</div>
</form>
</
body>
</
html>

 なりの接戦でした。(4)も(2)と同様にシンプルであり、とても難しい決断でした。しかし今回は、(4)はあまりにも普通であり、(2)ほど感動させたとまでは言い切れないため、最後的には(2)がグランプリに相応しいと判断しました。

 グランプリの(4)も評価されるべき存在です。もしもわたしが新人研修の講師役だったら、無難に(4)で書いておけと言うでしょう。それほどの接戦でした。

最後に

 のコラムでは、「XML」を切り口にしていろいろ書いているのですが、今回はとうとう「XML」が一度も出てこないんじゃないかという勢いでした。しかし、最後の最後に「XHTML」という反則技を使って「XML」を無理やり登場させました。何とか帳尻合わせができたでしょうか?

@IT Special 注目企業
@IT Special ラーニング

エンジニアライフ 最新の投稿コラム

@IT自分戦略研究所 新着記事

エンジニアライフ スポンサー

コラムニスト プロフィール

はやしさとし
(株)アット・フォース所属。デザインと文章を勉強中。

- PR -
@IT Special 注目企業
インデックス

@IT Special ラーニング