どうしてTitanium Mobileなの?
ウェブ開発者がiOSやAndroid向けアプリを作ろうと思い立った場合、今なら大きく分けて2つの選択肢があります。ひとつは他の人たちと同じようにObjective-CやJavaで素直にアプリを作ることです。まあ、当たり前ですね。もうひとつの方は、PhoneGapやTitanium Mobileのようなサードパーティーのツールを利用してJavascriptなどウェブ開発者の慣れ親しんだ言語で開発するやり方です。それぞれ一長一短があります。先のやり方では、ネイティブな開発用言語だけあって全ての機能を最大限に活かすことができます。AppleやGoogleも最大限の開発支援を提供してくれることでしょう。しかし、Objective-CやJavaに慣れ親しんでいた人でなければ学習曲線がなかなか上昇してくれないかもしれません。特にウェブ開発者はWebObjectsをやっていた人でもない限りはObjective-Cに馴染みの無い人が多いでしょう。また、ヘッダファイルを書くことやDelegateみたいなまだるっこしいデザインに疲れてしまうかもしれません。そんな場合、サードパーティーのツールで素早く開発しながら徐々に慣れていく方が安全なやり方といえます。一方で、サードパーティーのツールには最上位のベンダつまりAppleやGoogleの意向でいつ排除されてしまうかわからないというリスクもあります。これまで見たところでは、今年や来年にそんなことが起きるとは到底考えられないのですが、それでも細かいトラブルはあるでしょう。
以上のような状況を鑑みるに、もしあなたがObjective-CやJavaでの開発に不安が残る状態であるなら、迷わず後者の方を選択するべきでしょう。その上で、自分の開発しているプラットフォームについて知ることは重要であり、そうであればいずれはネイティブな言語での理解が必須になるでしょうから、得られる知見を最大限に活かしてObjective-CやJavaでの開発について学んでいくのが理想です。例えば、PHPを使って開発をしていても、それだけしか知ろうとせず、ウェブサーバやPHP自体の実装といった抽象化されて隠された部分に分け入って進もうとしない人が、筆者の経験ではありますが、競争に耐えうる優秀な人材であった試しはありません。幸いにもサードパーティーのツールにはソースコードにアクセスできるものもあるので、良い手本になることがたくさん見つかるでしょう。
では、数あるサードパーティーのツールの中で、一体どれを選べばいいのでしょうか。
もちろん、おみくじで決めたとしても、それは当人の責任の範疇ですから、全く構いません。しかし、それでもやはり、いくらなんでももう少し真面目に考えないと不安になるかもしれません。なので、そうですね、それぞれのツールの特徴を掴んだ上で判断する方がいいでしょう。私自身も決定的な答えを用意しているわけではないので、知っている範囲で自分の意見を述べたいと思います。情報は最新とは限りませんので、ここは違う、いや今はこうなっている、などなどご意見あれば是非聞かせてください。いずれにせよ、現段階ではちょっとした宗派の争いみたいになりがちな話題なので、リラックスしてお読みくださいね。
サードパーティーのツール、と上ではひとくくりにしましたが、大きく分けるとこれも二種類に分かれます。ひとつはPhoneGapやRhodesのようにHTMLとJavaScriptで作ったUIをWebView(UIWebView)を使って表示させる、ウェブアプリとネイティブアプリが合体したようなもの、もうひとつはTitanium MobileのようにネイティブなAPIを叩いてJavascriptで記述しながらネイティブアプリとして動作するものです。ここでは実際に使ったことのあるPhoneGapとTitanium Mobileを比較します。
私見では、PhoneGapのいいところは第一にそれがシンプルであることです。例えば生成されるJavaのクラスは非常にシンプルで、実際に使ってみたところカスタマイズも容易でした。APIも数えるほどしかなく、プラグインの作成もそれほど難しいものではありません。また、UIはHTMLとJavascriptで作るので、ウェブ開発者やデザイナのこれまでに培った技術を活用することができそうです。
それに、例えばFacebookアプリは現在PC向けのものはHTMLで作られていますが、モバイル向けも今後は同じくHTML5を利用して記述され、Facebookのモバイル用アプリ内で動作するといったものになっていくことが予想されます。クロスプラットフォームでの開発が容易なのはHTMLの強みですから、こうした流れにソーシャルゲームのプラットフォームも追随していくのではないかと思います。
しかし、欠点もないわけではありません。jQuery MobileやSencha Touchといったツールを使ってなるべくネイティブアプリに似せることは出来ますが、それでもUIはネイティブなものではありません。これらのツールキットはまだ開発されてから日も浅くベストプラクティスも少ないので、開発はお世辞にも快適とはいえないのですが、それなのに特にiOSではHTMLとCSSででっち上げた「ネイティブっぽい」UIの「偽物」っぽさが際立ちます。動作もまだまだ快適とはいえません。またネイティブな機能への橋渡しをしてくれるAPIも豊富とは言い難いので、少しでも複雑なことに挑戦すると結局Objective-CやJavaでプログラムを作成する必要が生じます。UIレベルの話ならまだしも、例えばiCloudへの対応といった要求にはツール側での対応を待つかそれなりの工数を費やしてプラグインを作成することになってしまうでしょう。それに、これは年月が解消してくれる問題なのかもしれませんが、例えばSnapdoragonの第1世代のIS03のような貧弱なハードウェアではWebViewのようなリソースを消費するものはどうしても動作が遅くなります。オリエンテーションの変更の際にレイアウトが酷く崩れるといったユーザに不安を与えるような現象が発生することもあります。
最近、PhoneGapの開発元がAdobeに買収されることが発表されましたが、資金的には大きな後ろ盾を得たと同時に、大企業であり、これまで数々のプロダクトをディスコンにしてきたAdobeにその命運を握られてしまったともいえます。
以上、駆け足ですが個人的に思うところを述べてみました。先ほども書きました通り、ここは違う、いや現在はこうなっているといったご意見などございましたらお知らせください。
さて、その一方でTitanium Mobileの場合、Javascriptで記述した内容は評価された後にプロキシを通じてiOSやAndroidのAPIに渡されて実行されるため、実際に動作するのは通常のアプリと同じものなので外観は全くネイティブなアプリと変わりません。と同時に、Titanium.UI.WebViewというものが用意されているので、やろうと思えばHTMLとJSでUIを作ってしまうことも可能です。またこのJSとネイティブな機能を繋ぐのも非常に容易なので、この点でも大きなアドバンテージがあります。動作速度はネイティブアプリと比較すれば、インタプリタとコンパイル言語ほどではなくても、まあある程度の差はあります。しかし、シビアな反応が求められるゲームや電子書籍リーダといった特定用途のアプリでなければ実際に問題になるほどではありません。ネットワーク越しにデータをやり取りするアプリ、ウェブサービスのフロントエンド用アプリとして利用するには十分といえます。それに、驚くべきことに、最近ではQuickTiGame2dのような高速で動作するゲームエンジンも開発されていますので、ゲームの開発に利用されるようになる日も近いでしょう。また、このようなサードパーティーのモジュール開発も盛んで、Open Mobile Marketplaceで有料、無料を問わずたくさんの機能拡張用モジュールが公開されています。Githubにソースコードが公開されているものも少なくありません。
それから、jQuery MobileやSencha Touch(Ext.JS)といった一種独特なJavascriptよりも、commonJSといったモダンなJavascriptで記述することが推奨されているのもポイントです。最近ではNode.jsのようなサーバサイドのJavascriptもありますが、Titanium MobileのJavascriptもCoffeeScriptやcommonJSのような今時の技術を習得する近道となるでしょう。というのも、Titanium Mobileは基本的にはよくあるイベント駆動型のGUIのプログラミングなので、Node.jsのようなコールバックにつぐコールバックの連続にも面食らうことはありません。
と、いいことばかり並べましたが、もちろん問題もないわけではありません。Aptanaを買収してEclipseベースの独自のIDEがリリースされましたが、Eclipseがそうであるように人によってはあまり快適とはいえないものです。もちろん使わないで開発することも可能ですが、最初はやはり公式なツールを使いたくなる方も多いでしょうから、そこら辺で面食らうこともあるかもしれません。またビルドスクリプト内部にビルドにかかる時間短縮のため高速化する工夫があるのですが、何度も繰り返してビルドするうちにそれが邪魔をしてアプリの挙動がおかしくなることがありますので、ときどきCleanしてあげる必要があるといった癖のあるところも見受けられます。また海外製品にありがちなことですが、Pythonを使ったビルドスクリプトはUTF-8のMac OS Xで日本語の処理に問題がある箇所が多数ありますのでアプリ名称やプロジェクト名、ソースコードのフルパスに日本語が含まれていると辛い目に遭います。その辺りは、日本語でも有志によるサポートコミュニティがありますので、活用してください。
これらは今後改善されるべきことではありますが、一方で大半は公開されたソースコードから追いかけることも可能なことであり、ついでにいえばパッチを送って直してしまうことだって出来ます。個人的には、いつか大金持ちになって暇を持て余すようになったら、面倒の多いPythonの部分を全部Rubyにしてしまいたいと思っています。また、Titanium Mobileを入り口としていろいろと学びましたが、逆にネイティブな言語で開発しなくてもいいやという気にもなってきました。やっぱりDelegateとかってうんざりますよね?
以上、駆け足で比較していきましたので粗雑な部分、間違いなどもあるかもしれません。上にも何回か申し上げましたように、これは違うぞ、といったところがあればどしどしご指摘ください。よろしくお願いします。
Popularity: 1% [?]
ImageAsResized for Androidの問題
指摘を受けたので調べてみましたが、Titanium MobileのAndroid用モジュールとして公開しているImageAsResizedモジュールにはちょっとした問題があります。
例えば、ここになんともいえず愛らしい息子の写真があるとします。縦横サイズは1536 × 2048ピクセルです。ちょっと大きいのでここでは縮小して表示しますね。

これを半分(768 x 1024)にリサイズします。大きいので表示は縮小します。

全く問題ありません。
じゃあ、1/8にしてみましょう(192 x 256)。こちらは実物大。

全然問題ありません。パパは萌え死にそうです。
ですが、これを1/10(153.6 x 204.8)にしようとすると、おかしなことになります。

あれ?切れてるよ!?まめちゃん切れてる!許せない、もう絶対許せない!
思わずモンスターペアレントになってしまいました。なぜこんな現象が起きるかというと、このモジュールはAndroidのBitmapクラスを利用しているのですが、こいつがbitmapデータの作成時に縦横サイズとしてintegerしか受け付けてくれないからです。1/10に縮小しようとして縦横サイズをfloatで指定しても途中でキャストされてしまいます。そうなった場合、縦横比もおかしいのでうまくリサイズされなくなります。モジュールは内部的にはメモリ節約のためいったん近似値までリサイズするようになっているのですが、どうやらそこから先はこの状態だと細かいリサイズをしてくれないで画像を切り取って処理してしまうようなのです(この辺の理解は適当)。
元々、このモジュールは同時期に作ったCropImageモジュールと併用して、縦横サイズが前もって予測できた上で使うことを前提としていたので、その辺りは細かい調整をしていませんでした。で、今日ちょっと質問されたので眺めてみましたが、上のような事情でうまくいきませんでした。何かうまい手はないでしょうか。例えば縮小する際に縦横サイズを指定するときは最大公約数を計算してどちらもちゃんとintegerになるようなヘルパーを用意するとかですかね。
Popularity: 1% [?]
2011年を振り返り、2012年の目標をたてる
2011年の収支を計算してみましたが、会社に勤めている頃よりはずっとマシだとはいえ、当初思っていたほど稼げたわけでもないですね。ナイスな未回収金を発生させてしまったこともあり、終盤になって年収が大幅に減ってしまったのが痛いです。うちは働き手がぼくだけしかいないので、こういうことが続くと一家で路頭に迷うことになりかねません。さすがに落ち込みましたが、以前お世話になった方々に相談していろいろとお力添え頂きましたので、なんとか春先には挽回したいものです。基本契約書は大事ですね。
来年からどうやっていこうか、考えてみました。別に好きでひとりでやってるわけではないので、どうしてもフリーランスを続けたいわけではありませんが、ここまでボッチだと我が人徳の無さはもはや人類史に足跡を残すほどであると考えるのが妥当だと思います。かの偉大なるポール・グレアムもこんなことを書いています:
創業者が1人であるのは何が問題なのだろう? まず何より、それが不信任投票だということがある。それはおそらく、その創業者が一緒に会社を始めてくれる友達を誰も見つけられなかったということを意味する。これはすごく憂慮すべきことであり、彼の友達は彼のことを一番よく知っている人たちだからだ。
実に身につまされる話です。これだけハッキリと不信任決議を突きつけられているのですから、いい加減に目を覚まして、どこかしっかりしたところで落ち着いて勤め人をやるのが筋というものです。そんなわけで、2012年は勤め先を探す年にすることにしよう。それまでには、いくつか考えていたプログラムを作って発表しておきたいので、頑張ります。
Popularity: 1% [?]
【Titanium Mobile】新しいアプリを作成しました
今回はリモートの音声データをストリーミング再生、またはダウンロードして保存するアプリを作成しました。音声データは今後どんどん追加されていきますが、新着データがあればトップ画面を表示中にTwitterクライアントみたいに勝手に追加されていきます。
TEDみたいな感じで、回線状況に関係なく再生したい方はダウンロード、ちょっと聴いてみたい方はストリーミングを選べるようになっています。ダウンロードしたデータはプレーヤー画面のスライダーを操作して好きなところから再生することができます。
Titanium Mobileで苦労したところはこの再生画面で、最終的にはTitanium Mobile自体に手を入れてしまいました。プラグインにしてもよかったのですが、それは今後の課題です。簡単な変更で動画プレーヤーの実装が楽になるので、これは実装してほしいんですけどねえ。
Titanium Mobile側の変更は以下の通り:
diff --git a/iphone/Classes/TiMediaVideoPlayerProxy.m b/iphone/Classes/TiMediaVideoPlayerProxy.m
index 93cd37c1..3ad7116 100644
--- a/iphone/Classes/TiMediaVideoPlayerProxy.m
+++ b/iphone/Classes/TiMediaVideoPlayerProxy.m
@@ -660,6 +660,11 @@ NSArray* moviePlayerKeys = nil;
}
}
+-(void)setCurrentPlaybackTime:(NSNumber*)time
+{
+ [movie setCurrentPlaybackTime:[time doubleValue]];
+}
+
-(NSNumber*)currentPlaybackTime
{
ONLY_IN_3_2_OR_GREATER(currentPlaybackTime)
@@ -1172,4 +1177,4 @@ NSArray* moviePlayerKeys = nil;
@end
これでスライダー付きの動画プレーヤーが簡単にできちゃうんですが、実は困ったことに1.8系からは現在の再生時間をこれまでと1,000倍も違うミリ秒単位で返すようになったので、スライダ部分は今後は更新が必要になります。地味に嫌な仕様変更です。
音声再生中にsetIntervalしたobserverが再生状況をみてスライダーを同期させるので、手で触ってスライダーを動かしたのと区別する必要があります。そこでtouchstartイベントを取得して、終わったらtouchendで解放するようにしました。
###
playerはTi.Media.createVideoPlayerしたオブジェクト
progressはTi.UI.createProgressBarしたオブジェクト
###
moved_by_user = false
progress.addEventListener('touchstart', (e)->
moved_by_user = true
return
)
progress.addEventListener('touchend', (e)->
slider_value = e.value
if player.duration
to = parseInt(player.duration * (slider_value / 100))
player.setCurrentPlaybackTime(to)
moved_by_user = false
return
)
observer = ()->
if moved_by_user == false
if player.currentPlaybackTime > 0
current_time = player.currentPlaybackTime
val = current_time / player.duration * 100
progress.value = val
return
timer = setInterval(observer, 1000)
こんな感じで実装しました。フォーワンファースト社のみなさん、辛抱強くお付き合い頂きありがとうございました。
Popularity: 1% [?]
2011年のオークランド・アスレティックス
この数年(2009はこちら、2010はこちら)、何の希望もないままシーズン開幕を迎え続けているオークランド・アスレティックスだが、2011年はちょっと違っていた。まず、先日FAになった途端に女関係の悪行がバラされてざまあみろな岩隈の獲得を目指すついでに、もう先は見えたけど若いからまだ獲得に名乗りを上げるチームがあると見越して先発マッツァーロを放出、見返りにカンザス・シティから怪我で安くなっていたデヴィッド・デヘススを獲得した。それからジェイソン・ワースに大金を注ぎ込んだ愚かなワシントン(案の定ワースは今年ダメだった)から弾き出された長打力と選球眼に優れたジョシュ・ウィリンガムを安値で獲得したのはビリー・ビーンの真骨頂だった。岩隈の獲得には失敗したけれど、怪我のためテキサスで出場機会に恵まれなかったブランドン・マッカーシーを獲得してただでさえ分厚い先発投手陣はさらに厚みを増した。怪我で途中出場できない時期もあったが、終わってみればそのマッカーシーの投球内容がリーグでも屈指のものだったのはうれしい誤算だ。ついでに、選球眼に優れた長距離打者で選手寿命の黄昏時というオークランド好みの選手になった松井も安値で獲得、これで外野手とDHは揃った。選手たちが例年通りくらいの成績をあげれば、ひょっとしたらプレーオフも夢ではない、かもしれないくらいの期待をもたせてくれる陣容だ。内野は2010年にリーグ屈指の高い出塁率と一塁手としては例外的に長打力のないことでも注目されたデイリック・バートン、相変わらず守備の素晴らしいマーク・エリス、元ドラ1で多少荒っぽさもあるけど強肩の守備が魅力的なペニントン、長打力が期待されるクーズマノフという面子。これに不動のキャッチャーとなったカート鈴木、高出塁率が期待されるコナー・ジャクソン、未来のスターといわれ続けたままだが今年は膝の手術からの復帰を目指すライアン・スウィーニーを加えたメンバーは、それなりにやってくれそうな気がしないでもなかった。
4月中に夢を砕いてくれたのは、せめてもの優しさだったのだろうか。蓋を開ければ、キャリア最低の成績に終わった松井とデヘスス、あまりにお粗末な成績に最終的には放出されたジャクソン、トリプルA送りとなったバートンとクーズマノフと死屍累々たる有様。とうとう開幕戦に出ていた内野手はシーズン途中にはペニントンだけとなってしまった。スウィーニーはパワーの無さだけが目立ち、ココ・クリスプはやることがないからだろうか、ひたすら盗塁し続けた。おまけにシーズン途中で監督もクビになった。それだけではない。ピッチャーにしても、長期契約を結んだ途端に1年以上リハビリが必要な怪我をしたブレット・アンダーソン、同じくシーズンを棒に振ってしまった昨年の完全試合男ダラス・ブレイデン、相変わらず2ヶ月くらい怪我で休むクローザーのアンドリュー・ベイリー、中継ぎで8敗という前半戦最強の壊し屋っぷりを見せつけたブライアン・フエンテス、もう何の怪我か忘れたけどとにかく離脱した先発のタイソン・ロスなどなど、たぶん呪いとかの超自然的現象でいいんじゃないかと思うほどの惨状だ。
もちろん、悪いことばかりではない。ウィリンガムは前半こそひどい成績だったが、ただでさえバッターに不利なことで有名な広い球場をホームグランドにして、終わってみればキャリアハイの29ホームランだったのだから立派なものだ。これでサラリーが跳ね上がり再契約できなくなって他所のチームにかっ攫われることになる(2012年からはミネソタで長期契約となった)のを考えなければ、とても素晴らしい。そして怪我ばかりの兄リッキー・ウィークスと同じくずっと怪我に苦しんでいたジェマイル・ウィークスが華々しくデビューを飾り、そのまま好成績で年間を通した活躍した(その結果チーム在籍年数が最も長かったマーク・エリスが放出されてしまった…)のも明るい話題だ。もっとも、負け続けて起用されるようになった若手が増える中、この数年で最も期待されているクリス・カーターやマイケル・テイラーが全くメジャーでは通用しないことも分かったのだが。まあ、他にもトリプルAで素晴らしい成績を叩き出したギレルモ・モスコソがメジャーでも十分活躍できることもわかり、それから遂に公開された映画『マネーボール』は批評家ウケもいい手堅い出来だった。
オークランドの迷走の原因といわれているのが、本拠地の移転問題が解決していないことだ。数十キロ離れたサンノゼにシスコシステムズから提供された土地があり、そこに球場を建設して移転する計画が持ち上がってからもう何年かになるが、2012年の1月まで決着がついていない。サンフランシスコ・ジャイアンツのフランチャイズでもあるので、その辺りの問題が解決していないせいだというが、どうやら今年結論が出るという噂である。そうなると、移転は2014年ということになり、その時点までに強いチームを作るという本当の再建モードになるわけだが、この冬の大胆なトレードをみるにつれ、どうやら本当に今月には移転問題の決着がつきそうな感じだ。
というわけで、2012年からのオークランド・アスレティックスは、今年と同じかそれ以下の期待しか出来そうもない。噂はあったが、本当にオールスターに選出された経験のあるピッチャーを全て放出してしまい、放出した選手もみんなまだ若かったが、それよりさらに若い選手ばかり揃えたところなど、むしろトリプルAやダブルAの試合の方が面白いんじゃないかと思わせるくらいだ。
といいつつ、でもそんなトレードで獲得したジャレッド・パーカーは実は次のダン・ヘイレンになるんじゃないか、トム・ミローンはダラス・ブレイデンあるいはもっと凄くてトム・グラヴィンみたいになっちゃうんじゃないか、などと妄想をたくましくしてしまうのが、ファンというものでもある。
Popularity: 1% [?]
ランチ(ジョエル・スポルスキー)
まあどれも面白いわけだけれど、和訳がないジョエル・スポルスキーのエッセイがすごーく面白かったので訳した。いや、この文自体が面白いんじゃなくて、そういえばいろんなところで働いたけど、一緒にランチするところとそうでないところじゃ、ずいぶんと違ったし、そこで出てくる会話の内容こそが、仕事の面白さのいい指標になったよな、と思い出したので。みなさん、どんなランチを過ごしてますか?
———————————————————————–
ランチ
いつもランチのときはどうしてる?どこで食べる?誰と?
毎日ランチを一緒に食べるチームと過ごしたことがあるけど、素晴らしいものだった。そうしないチームと過ごしたこともあるけど、毎日のランチの時間はひどく寂しいものだった。
大きなハイテク起業にはたいていカフェテリアがあって、無料(Google)だったり有料(マイクロソフト)だったりする。こういう会社にだって毎日食事を一緒にしようと努めているチームもあるけど、ほとんどのチームはそんなことはしない。ランチタイムにこの手の場所をうろついてみると、「ランチミーティング」をスケジュールに入れていた2人組をたくさん見かけることになるわけだけど、同時にひとりぼっちで食事している寂しい人たちも悲しいくらい大勢見る羽目になる。きっとその手の人たちは食べながら本を読んだりメールをチェックしたりしているから悲しんでいるようには見えないだろう。自分の机にランチを持って行って食べるからカフェテリアに独りで座ることもないかもしれない。きっと本当に人が嫌いで独りで食事する方が幸せなのかもしれない。あるいは、口でそう言っているだけなのかもしれない。
GoogleやMicrosoftでは、カフェテリアはとても混雑するので、ボッチの人は他のグループと一緒に座らなければいけない。というのも、テーブルを自分だけで専有するだけの余裕がないからだ。ときどき、一緒に座ったグループの人たちがボッチを会話に引き込もうとすることがある。でも大抵の場合、ボッチは社交的コンタクトの必要性を回避するためにスマートフォンでFarmbookをプレイするのに完全に没頭しているふりをするよう強いられている。すいません、自己紹介したいのはやまやまですが、キャベツのアップデートが忙しくて。
ランチをどこで誰と食べるのかはみんなが考えているよりもずっと大きな問題だ。心理学者の意見は決まっている。子供の頃を思い返せば、特に学校時代、それも中学生の頃は、どこで誰と食べるのかは記念碑的重要事項だったのはいうまでもない。どんな集団に入っても、たとえそれがヲタ連中であっても、ひとりぼっちで食事するよりずっとましだ。ボッチとギークにとって、学校のカフェテリアで一緒に食事する相手を探すのは多大なストレスの原因となり得るのだ。
私にいわせれば、仕事の同僚と一緒に食事をすることの重要性には議論の余地はない。運まかせにするには重要すぎることだ。だから私たちは、小さい丸テーブルたくさんではなく、長いテーブルで一緒に食事することにしている。そのため、新しくこの会社で働くことになった人が隅っこで独りで座るなんてことはあり得ない。お客さんが居れば、みんなで一緒に食事する。
Stack ExchangeとFog Creekは完全に分離した会社組織だけれど、それぞれのオフィスが同じビルにある利点を活かして毎日一緒に食事している。多くの人たちが仲間になって毎日同じ面子で固まっているが、それでもこれが実現できてとてもよかったと思っている。
Fog CreekにもStack Exchangeにも行き当たりばったりなことはたくさんあるけれど、ランチは違う。10年前、マイケルと私は最高の仕事場を作るというかなり野心的な目標を立てた。一緒に食事するというのは人間であること、人間らしい職場を持つことにとって重要な意味があり、初日からそれは私たちの持っている価値の一部であったわけだ。
Popularity: 1% [?]
フリーランスになって経験したトラブル
IT業界は新しいように見えても実際には汎用機の時代など含めてもう数十年の歴史があるわけですから、それなりに古株な人たちもたくさんいます。また他業種から流れてくる人も大勢いるので、決して特殊なタイプの人間の集まりではありません。したがって、どこの業界にもいるゴロツキや詐欺師、ヤクザや社畜、セールスガイはこの業界にもちゃんといるのです。
もっとも、貴方がよっぽどのエンタープライズ系の仕事をしているのでなければ、そんなにすごい大物な人に出会うことはありません。筆者のような零細の技術者であれば、巡り会うのはせいぜいケチな小悪党くらいのものです。こんなのに手こずるとは余っ程ダメ人間なんだなと笑われそうですが、これから同じような目に遭うかもしれない人たちのために、フリーランスになって出会った困った人たちについてまとめておこうと思います。ちなみに筆者は自分でコンテンツを立ち上げてそれで食べているわけではなく、受託案件で生活をまかなっているので、企業や企業の担当者との話に限定されます。
正直、恥をさらすようなものですが、それでも何かの教訓になればいいと思うので書いていきます。それにしても、トラブルのほとんどが「受注/発注処理があいまいである」ことが原因だったのがなんともいえません。
(1)受発注処理がきちんとしていない隙を狙う
営業と開発を同時にこなすのはなかなか大変なので、どちらかがおろそかになりがちです。通常、受託案件は見積りから営業の交渉があり、金額が決まって案件の発注、受注という流れになりますが、例えば知人やクライアントの紹介などで担当者同士で話がまとまり、正式な手続きなしで仕事が始まることもあります。そんな場合でも、見積りを出すこと無しに仕事が始まることは経験上一度もありませんでしたが、逆に受注と発注の処理は省略されるか後回しになることが結構ありました。
しかし、残念なことに、この手のケースは大抵後で問題が起きました。
例えば、ある開発案件では、新規案件のために200万の見積りを提出しました。B2Bのサイト構築で、内容はオーソドックスなウェブサイトなのですが、短期間での開発が求められるためRuby on Railsでの構築を提案したところ、特に問題ないとのご回答を頂き、何度か打ち合わせた後、スケジュールや素材が届いたので初期開発まで完了しました。正式な発注処理はなかったのですが、前に同じクライアントの別案件を請け負っていたこともあり、その流れで他とコンペになってもいなかったので、その辺りの処理は相手方にお任せ状態でした。開発は特に滞りなく進み、期日にも間に合ってめでたしめでたし、となるはずでした。
ところが、その後案件は二転三転します。サイト規模から事業計画まで、クライアント側で次々と変更が発生し、サイト自体がオープンしません。途中大きな変更が入り、結局、4ヶ月後になってやっと検収が完了したのですが、ほぼ同内容のものを二度構築するような目に遭いました。それでも、終わってしまえばまあよしとしましょう。残るは請求などの事務処理だけです。200万の案件ですから、以前会社に所属していた頃はなんでもないような金額ですが、フリーランスにとっては大金です。さらに、来年早々に出産を控える家庭にとってはありがたい話です。トータルで二ヶ月くらいは働いたので、報酬としては悪くありません。
しかし、この段になって急に呼び出しをくらいました。一次受けと筆者の間に入っていた業者が金額の調整がしたいというのです。なるほど、実はこの案件、最後になって要件の追加があり、その分については後日開発となっていました。しかし追加分については、当初の見積りの金額でカバーしても問題ない規模だったため、特に追加請求はしないことにしました。そのため、総額が支払われなくても追加分を除いた分でいったん清算する方が、追加分の検収を待ってまた支払いが延び延びになってしまうより余っ程ありがたいくらいだったのです。ところが、待ち合わせ場所で聞いたのは意外な話ばかりでした。開口一番、この案件の見積りは幾らだったのかと質問されました。見積りを提出したのはもう何ヶ月も前のことです。しかし出したことには変わりはないのですから、それを忘れたというのは幾らなんでも失礼です。何かあるぞと、今は手元にないので確認したいと返答したところ、その場で実際の稼働状況について聞き取り調査をされました。おおまかなところを答えたのですが、先方の担当者は渋い顔をしています。そして、おもむろに紙を取り出して計算を始めると、顔を上げて「これじゃ厳しいですね」と言い出しました。「あなたの日当が3万円として、総額にすると約70万円、でもこれだと予算を越えちゃうんだよね」「予算?予算って幾らなんですか?」「30万円」
驚きました。まず、なぜこの人がこちらの日当を勝手に決めて計算しているのかがわかりません。業界の相場というものがあるのかもしれませんが、それはそれ、こちらの見積りは見積りです。だいたいバイトじゃあるまいし、そんな日当で仕事をするつもりなど毛頭ありません。それから、なぜ今頃予算の話になるのでしょう。それに納品してから金額を調整するというのはいったいどういうことでしょうか。もう、わけがわかりません。業務の中にはサーバ構築など技術料をプログラム開発とは別にしたい項目も含まれるので、単純に日雇いの計算などされるいわれはありません。そもそも見積りと全く関係のない、しかも恐ろしいほど低い金額で話を進めようとする意図が理解できません。
「ちょっと待ってください、最初にこちらから提出した見積りがありますよね?その金額は200万円です。それでOKというお話だったので作業を進めたんですよ。そこに交渉の余地なんかありません。そもそもこの金額は案件の費用の総額の何パーセント分なんですか?」
「それは確認していない」
「だいたい、この金額の案件なら、最初から受注なんかしていませんよ。もちろん、信用していたからといって受発注をきちんとしなかったこちらにも非があります。なので、まずあなたのおっしゃる金額というのは、お客様が開発は何パーセント納品/検収済みで、それに対して総額の何パーセントをお支払いするとお考えなのか確認してください」
「確認しましょう」
「それもわからないということなんですね。これが総額という可能性もあるということですか?」
「確認しましょう」
「(絶望して)今後の開発については、正式な受発注手続き無しには一切進めません。それはご理解ください」
こんな不毛なやり取りだけで打ち合わせは終了しました。この規模の案件ですから、それなりの準備や他のクライアント様とのスケジュールの調整も必要になります。年間で受注する仕事の量もこの見積りをベースにしているわけですから、それが大きく計画と異なることになってしまいます。言い方は悪いですが、これは立派な詐欺です。ソースコードの引き上げも含めて現在いろいろ検討しているところです。
というわけで教訓。大人は信用なんかで仕事を進めてはいけません。営業職には基本中の基本でしょうが、開発の人は忘れがちなので書いておきます。受注、発注は双方でハンコを押した書類が揃って初めて完了です。それまでは開発に着手してはいけません。
(2)業務内容が全て記載されていないのにつけ込む
見積りが複雑になり、案件が当初の規模からころころと変わって何度も見積りを出し直すことになった経験はあるでしょうか。ここに問題が発生する隙が生じることがあります。何度目かのやり取りを経て「では、最後にAndroidとiPhoneのアプリ開発、両方の見積りをください」そんな依頼で提出した二通の見積りで開発が開始された案件で、開発終了後に請求を送ったところ、いや、片方の分しか発注していないと突き返されたことがありました。そういうつもりじゃなかった、とは担当者の弁ですが、意図がどうこうという問題ではありません。しかし、確かに見積書には「スマートフォン向けアプリ開発」と書かれているので、完全に間違っているとはいえませんでした。それはそれで、こちらのミスではあります。片方分の支払いは滞り無く、また担当者に謝罪はされましたが、それでもこちらとしては大損しただけなので非常にがっかりしました。
要件が完全に定まっていない場合、変更要求にどこまで応じられるかの案分も大事です。営業の人は仕事を取ることに必死ですから無茶な要件をねじ込むことも珍しくはありません。携帯サイトを開発していたつもりが、いつの間にかPCに対応し、スマートフォンに対応し、挙げ句の果てには店舗据え置き機器からFelicaで認証する機能まで実装せざるを得なくなった案件がありましたが、この手の話はザラにあります。いくつかの機能は別途費用を請求できましたが、他は営業に押し切られました。別の案件では管理画面の機能がいくつか後になって追加されてしまい、別途請求しようとしても「いや、みんな頑張ってるんですから」と妙な説教をされる始末。
さらに難しいのが、社会人は他人に親切をするのは決して正しいことではないという問題があります。何かトラブルを起こした人がいたとして、親切心から対応してあげるとします。例えば要件定義が下手で必要な機能が含まれていなかった場合、仕方がないので追加費用無しで開発してあげると、その人もきっと喜んでくれるでしょう。ところが、社会人というのは親切を親切で返していたら上司に怒られてしまいますので、こちらのミスで何か実装が抜けていたりなんかした場合には、途端に手のひらを返して責めてくるのが普通です。社畜たるもの「上司>>>>>>>>>>客>>>越えられない壁>>>>下請け」という序列を骨の髄にまでインプットしているのが当たり前なのですから。また、そもそもトラブルを起こす人というのは、それなりの理由(無能、怠惰、口に出すのもはばかられるほどの悲しい理由など)があるのですから、この次もまた何かやらかす可能性は高いはずです。今回はたまたまそれがこちらが親切にすれば収束するものであったとしても、この次はそうはいかないかもしれません。そのとき、この人が言い訳として問題をあなたのせいにしてしまうことはあり得ないでしょうか。下請け業者のせいにすることは社会人にとってアリを踏みつぶすくらいの良心の呵責しか感じられない行為だということを理解しておく必要があります。
(3)損失を弁済させようとする
企業間の取引であれば、基本契約やNDAなどは事務型の基本的な作業ですが、フリーランスのプログラマの場合、その手の作業はクライアント側で用意してもらうことも多いかと思います。または、そもそもそんなやり取りもなく開発して納品するケースもあるでしょう。
しかし、基本契約を結ばずに業務を請け負うと、トラブルが発生した場合に面倒なことになります。例えば、よくある契約にはソフトウェアのトラブルが原因で発生した損失については受注金額を補償の上限とする、みたいな条項が含まれています。これがないとどこまで責任を負うべきか不明確になり、裁判になると個人はどうしても弱いので負けることになります。また裁判にはならなくても、下請け業者というのは弱い立場なので無理な要求を飲まされることになってしまいます。クライアントとの間に別の業者が挟まっていたりすると余計にそうなることが多いでしょう。
というわけで、フリーランスの開発者には、ガチガチな契約か、損をしても知らんぷりする余裕のどちらかが求められます。
Popularity: 5% [?]
【Titanium Advent Calendar 2011:18日目】Titanium MobileでAndroid
この記事は、@astronaughtsさん企画の「Titanium Advent Calendar 2011」向けに書いています。
12月1日~25日まで毎日誰かがTitanium Mobileについての記事を書いていくというイベントです。
最近、よくいろんな方から「Androidの案件を受注してしまったけど、Titaniumで大丈夫だろうか」と相談を受けるので、そんな人たちを少しでも慰めるためにそれをテーマに書いてみたいと思います。
さて。AndroidでTitanium Mobileを使う場合の鉄則がいくつかあります。面倒くさがりな方のために先にまとめておきます。
【鉄則1】iOSを基準に仕様を作ってはいけません
【鉄則2】試験用にIS03とタブレットは必ず用意しましょう
【鉄則3】anyDensityでごまかせると思ったら大間違いです
それから、開発する上で外してはいけないポイントがいくつかあります。
【ポイント1】シングルコンテクストにしないとまずいことが起きる
【ポイント2】Javaは友達、怖くないよ
では、ざっとみていきましょう。
【鉄則1】iOSを基準に仕様を作ってはいけません
クロスプラットフォームの開発を楽にするのがウリのTitanium Mobileですが、iOSでは動作してもAndroidでは実装されていない機能がたくさんあるので、iOSのKitchenSinkを見ただけで仕様を決めると後で痛い目に遭います。考えてみれば当たり前の話で、これだけ大きく異なるiOSとAndroidの違いを抽象化しようとしても、どうしても漏れるものがあるのは火を見るより明らかです。漏れのある抽象化そのものですから。
最初に作ったAndroid用アプリ「AKB48大島優子 ボクの彼女」に取りかかったときには、リモートのムービーファイルを再生する機能がAndroidには実装されていないことを知りませんでした。Intentを起動して端末にインストールされた動画プレーヤーを起動して解決する方が断然楽なのでやり方はないか探しましたが、結局いったんChromeを起動させて、そこから動画プレーヤーを起動させる方法しかありません。でも、それだとムービーの再生が終わってバックボタンを押すと真っ白なブラウザの画面に戻ることになってしまいます。そんなのを作ってお金をもらってたら、詐欺ですよね。
そこで、リリースの際はTitanium Mobileのソースコードに手を入れて、直接動画プレーヤが起動するように変更して対応していたのですが、その後モジュールが書けることがわかったので、今ではMIMEタイプを渡すと適当なIntentが起動するこちらのモジュールを使って回避しています。とっても簡単なものなので、PDFビューワなどにも応用できると思います。
いずれにせよ、Android案件ではこんな苦労はしょっちゅうです。また、特に困るのがUI設計の問題です。例えばiOSでは上の画像みたいにナビゲーションバーが表示されて、その左側には何もしなくても戻るボタンがあり、また必要に応じて画面下部にタブを表示する、みたいな画面設計になるのが一般的なのですが、Androidだとナビゲーションバーというものは存在せず、タブも画面上部に並んでしまうので、どう転んでもiOSと同じものにはなりません。Android向けのアプリは、バックボタンやメニューボタンで遷移することを考慮する必要があります。なんといってもiOSと比較するとタッチセンサーの感度は微妙だし、小さな画面で正確にボタンをタッチするのは面倒くさいので、バックボタンを押しまくるユーザも多いのです。しかし、世の中というのは不思議なもので、何をどう勘違いしたのか、それでもUIを全てiOSと同じになるようにしろと要求する人が後を絶ちません。しかもその数は開発者の予想を遥かに越えてたくさんいることが最近の調査で判明しています。その手のプロジェクトは、iOSが用意してくれるボタンなどの機能をAndroid用にわざわざ画像でパーツを全部作って対応しようとするなど、無駄なコストがたくさんかかってしまっているので遠くからでもすぐにわかります。テストも倍以上になり、プログラムは複雑になり、それでいてiOSの偽物のような外観の、全く使用感の異なるパチモノが出来るだけなのですから、どうやっても結局誰も得をしません。WindowsとMacでもそうですが、UIを複数のOSで共通化しようというのはほとんどが無駄な努力だと思います。たいていのユーザはどちらかでしかそのプログラムを使いません。Microsoft Officeならいざ知らず、あなたのアプリをiOSとAndroidの両方で使うというユーザなんて、あなたが雇ったテスター以外は誰もいないでしょう。だから、もしあなたがiOSとAndroidで共通のUIのアプリを作ろうと頑張っているのなら、まあ多少はいいですが、そろそろいい加減に目を覚ましてください。
【鉄則2】試験用にIS03とタブレットは必ず用意しましょう
Androidマーケットにアクセスした端末に表示されるアプリは、その端末の画面サイズに適したものだけです。Titanium Mobileではデフォルトでたしかこんな感じで指定されていたかと思います。
<supports-screens
android:smallScreens="false"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="false"
/>
smallScreensに非対応にするとIDEOSみたいな端末ではそのアプリは利用できないことになります。シェアからすると別に構わないと思いますが、特殊な用途がある場合などは注意する必要があります。また、一般的な端末にも要注意なものがあります。携帯サイトの開発を経験された方なら誰もが開発者泣かせの癖のある端末をいくつか苦々しい思い出と共に心の中にしまってあるかと思いますが、スマートフォンでもその手のやつは根絶されたわけでは決してありません。代表的なのはauが只同然で配っていたためユーザ数の多いIS03です。こいつはなかなか癖のある端末で、例えばソフトキーの高さを除いた画面サイズを返してくれないのでレイアウトの調整に苦労します。またSnapdragon第一世代らしいハードウェアスペックの低さは想像以上です。
⇨ココ大事!
それから、Ti.UI.createAlertDialog()を使うとき、どうしてもダイアログが出ないことがあります。そんなときは、ダイアログの前にTi.UI.createWindow()してそのウィンドウにダイアログをaddしてみましょう。IS03のときだけに起きる現象です。内緒にしてぼくだけの競争優位にしようと思っていたのですが、口が軽いので白状します。
また、タブレット機の存在も非常に厄介です。画面を縦または横固定で使うアプリを作成すると、作る側のコストはとても低く抑えることができるのですが、普通のスマートフォンならそれだけで使い勝手に悪影響が生じることは滅多にありません。縦固定で使いにくいアプリなら大抵は横でも使いにくいからです。しかし、タブレットは重量があるので寝転がって使ったりする際に手で支えるのも大変なため、縦でも横でも好きなように変更できるのが望ましいです。ご存知の通り、これは開発者にとって地獄への道まっしぐらなので、せめて試験用端末だけでも用意しておきましょう。
【鉄則3】anyDensityでごまかせると思ったら大間違いです
iOSとAndroidの一番大きな違い(二番目は飲み屋でそこら辺の人に自慢できるかどうかの違いです)は複数の画面サイズに対応しなければいけないことです。以前はAndroid SDKのサイトに対応する画面サイズの一覧があったのですが、デバイスが増え続ける昨今、いつの間にかそんな資料は見かけなくなってしまいました。
一応、Android側でもanyDensityという仕組みを使ってこれに対応しようとしています。
「anyDensity = false というのは、そいういう対処をしていないので、コード側で設定しているピクセル値を解像度に応じて調整してください」ということです。 この場合、コード側で setWidth(10) とした場合と XMLで android:layout_width=”10dip”とした場合の大きさは端末の解像度によらず同じになります。
Titanium Mobileの場合、anyDensityはデフォルトでfalseです。つまりdipで指定したのと同じことになります。ところが、そもそも端末の縦横サイズがまちまちなので、複数のディスプレイで同じ画面構成にしようとすると大変なことになります。
この辺、資料を読んでもいまいちよくわからないんですよね。たぶん、書いてる人が悪いんだと思います。
例えば上の画像みたいなアプリで、赤く塗ったところをタップするとアクションが実行される、という機能を実現したい場合、その部分に透明なViewを置いてタッチイベントを検知する、みたいな作り方でなんとかなります。しかし、その範囲を指定するのに、端末の縦横サイズがバラバラではうまく指定することができません。
そこで、例えばこんな対応方法を考えてやってみたところ、結構うまくいきました。まず、背景となるviewにはbackgroundImageとして横幅が端末の横サイズに拡大/縮小されることを前提に、上下に余分な部分を残しておきます。次に、各パーツを以下の手順に従って配置していきます:
・画面中央の位置を取得する
・画面の横幅を10または100分割して1つの単位とする(例・1 andro_scale)
・各パーツのY座標は中央から何andro_scale上/下かで決める
・各パーツのX座標は左/右端から何andro_scale右/左かで決める
・各パーツのwidthやheightも何andro_scaleかで指定する
このやり方だと、どんなサイズの端末でも同じ距離の指定方法で動作しました。もちろん画面最上部や最下部に張りついたパーツなどは素直にtop = 0やbottom = 0とすればいいでしょう。
1 andro_scaleをどれくらいにするかで勝負が決まるところでもあります。あんまり大きいとタブレットで画面が大きく(解像度が低く)なった途端にズレが目立ったりします。
そういう意味では鉄則2の試験端末の用意は必須ですね。
【ポイント1】シングルコンテクストにしないとまずいことが起きる
最近ではAppcelerator社から出ているアプリのソースでも使われていることが話題になっていた、シングルコンテクストで記述する方法ですが、Androidだとおそらくこれをやらないととてもじゃありませんがうまくいかないと思います。例えば
・HTTPClientからPOSTリクエストが送信されない
・コールバック関数がたまにしか実行されない
といった症状にお悩みの方は、シングルコンテクストで記述しないと改善されません。その際、記述が冗長にならないようにいろいろと気をつける必要があるのですが、個人的にはsyrupという名前で公開されたこの手法がとても参考になりました。そして全部のアプリをCoffeeScriptで書き直しました。残念なことに、syrupという名前のCoffeeScript的Lispというのもgithubにあるので、名前については再考の余地がありますが、とても分かりやすいのでオススメです。これに、例えばデータベースの扱いやIO関連のユーティリティを用意しておけば便利です。いつも用意しているライブラリでは、例えばデータベースの扱いは下のようなモデルを用意するだけでテーブルがなければ作成、初期データの投入(あれば何もしない)まで勝手にやってくれます。
syrup.namespase 'MYAPP.Model', (exports)->
Model = syrup.use 'MYAPP.Model.Model'
class User extends Model
init:()->
this.property "id", "integer"
this.property "name", "text"
this.property "email", "text"
this.init_data.push {id:1, name:'ヒューバート・セルビー・ジュニア', email:'last_exit@to.brooklyn.org'}
this.init_data.push {id:2, name:'ダグラス・アダムズ', email:'adams_d@42.org'}
super
exports.User = new User('users')
簡単でしょ?これでusersテーブルが(まだ未作成の場合は)作成され、2行のデータがINSERTされます。
CoffeeScriptで作るノウハウがもっと溜まってきたらもっと公開して還元していこうと思います。
【ポイント2】Javaは友達、怖くないよ
ここまで頑張ったら普通はどんな残酷な悪魔でも許してくれそうなものですが、Androidの開発ではそうは問屋がビジネスしてくれません。実はこれまでJavaで何かを作ったことは一度も無い(一応、教養として一通りいじったことはある)のですが、できればこのまま一生避けて通りたいと思っていました。でも、Ti.UI.createToolbar()を指定しただけでこんなものを見せつけられるようでは余裕こいてばかりもいられません。
パンがないならお菓子を食べるのが真の王妃というものです。じゃなかった、ないならないで作ってしまうのが開発者というものです。そんなとき、ヒントになるのが、Titanium MobileのAndroid用モジュールのソースコードです。実はAndroidのカメラなどもモジュールとして作られているので、そこで使われているテクニックは自作モジュールでも利用できます。Intentを起動してコールバックを指定するとか、Intentを起動するだけとか、ごく普通に関数を実行するとかのサンプルはこちらをどうぞ。
そろそろ疲れてきたので仕事に戻りますが、他にもAndroidという二番手ならではのbkはたくさんあります。みなさんも、見つけた悪しき知恵は出来るだけウェブで公開して、同じ苦労を分かち合いましょう。そうすれば、プラットフォームとしてのTitanium Mobileの発展に貢献することができます。このプラットフォームが成長して機能が改善され、また良い人材が引き込まれてくるようになれば、この先もっといいことが待っているはずです。たぶん、きっと。
Popularity: 6% [?]
私は如何にして禁煙するのを止めてタバコを愛するようになったか
意味もなく事実と反対のタイトルにしました。
8月にタバコをやめました。たまに理由は?と聞かれますが、それは自転車を盗まれたことから始まります。年初に自宅に駐輪していた自転車を盗まれました。うちは玄関に人が近づくとライトが点灯する仕組みになっていて、自転車は玄関のドアの前にありました。上の子のところに友達が遊びに来ていて、送り出したときにはまだあったのですが、その20分後にタバコを吸いに外に出たところ、もう自転車はありませんでした。
そして、手にしたタバコを見つめ、いつものようにアスファルトに押し付けて火を消すと、最後の一本を吸い終えた私の中で何かが死に、同時に何かが生まれたような気がしたのでした。
とかいうことは全然なくて、普通に困ってひとしきり泣き言をほざいてから、盗難届を出してこの件は処理しました。しかし、これは人生の大きな転換点の前触れだったのです。
しばらく不便なまま生活していましたが、かみさんの実家に行ったとき、義父母に自転車を盗まれた話をしたら、義父が「じゃあこれをあげよう」と使っていなかった原チャリをくれました。古い型ですが、手入れがよかったのでちゃんと動きます。実は、長いこと生きてきて、これまでヤンキーっぽいからという理由で原チャリに乗ったことがほとんどありませんでした。たぶん、ほんのちょっとの距離を一回くらい、これも誤解の末に仕方なく乗っただけだったはずです。だいいち普通自動車運転免許だって30歳で取得したくらいですから、乗り物全般にほとんど興味がなく、二輪車なんてろくでもない嗜好品としか思えませんでした。でも、なんとなく話の流れで、これからはこの原チャリがぼくの通勤とかの足になってしまったのです。かみさんと近くのホームセンターに出かけてとりあえずヘルメットを買い、運転の仕方についてあれやこれやと教わりましたが、ここ埼玉から練馬の自宅まで、車でも小一時間かかります。でも原チャリを積むことも出来ず、ほぼ人生初の原チャリなのに、大通りを延々と走る羽目になってしまいました。
田舎道を原チャリで走るとたくさんの自殺願望の昆虫が目の中に次々と飛び込んできます。途中でゴーグルを買いました。大きな車に追い抜かれるときは死が具体的な姿で迫ってくる気がしました。アスファルトの路面がまるで1970年代のマンハッタンのように穴だらけなのを知りました。完全にビビりながらの走行でしたが、大通り沿いのコンビニで休憩していると、なんだか自分がいっぱしのライダーになったような気がしてきます。タバコをふかして、気分はまるでハーレーに乗るマルボロマンです。なんだか楽しいじゃないか。時速30キロ台でも、風を切って走っていることには変わりなく、片手をひねれば、もうどこにでも行けるんだという感覚は、魔法のような強さで人を引きつけます。
中年の危機は、男性にとっては、2つのかたちで現れるものなのだそうです。すなわち、若い女に走るか、バイクに乗りたがるか。
いつしか、通勤にもほぼ原チャリを使うようになりました。新宿、渋谷くらいなら原チャリで余裕ですが、五反田あたりまで行くと自分でも相当にいかれてると思います。山手通りの左端を原チャリでのろのろ走っていると、なんだかとても自由な感じがします。電車での通勤だと、ふと目に留まった場所で降りてみるなんてふざけたことが出来る余裕はないのですが、原チャリだったら真っすぐ帰るのも寄り道するのも気の向くまま、どのコースを通ってもいいわけです。たったこれだけのことが、ずいぶんと開放的な気分を演出してくれるとは知りませんでした。それに、原チャリって満タンまで給油しても400円くらいしかしないので、電車賃より安く済みます。交通費をもらえる立場にないので、それも好感触です。もちろん、読書ができるとか天気に左右されないといった電車ならではの特典はたくさんあるのですが、この気分だけは電車の運転手にだって味わえないものなのです。
そして、数ヶ月が経って、あることに気付きました。なんだよ、この俺様より気分良さそうに走る乗り物にのってる奴らがいるじゃねえか。そうです。原チャリは制限時速が30キロ、普段自動車に乗っているとあまりの遅さにすぐに追い抜くような邪魔くさい存在です。でも、渋滞のときは車の脇をすいすいすり抜けて小気味よく走る素敵な乗り物でもあります。しかし、この2つの特性を同時に昇華させて利点に変えたとんでもねえ奴らがいるではありませんか。そう、普通の、いわゆるバイクってやつです。むかつきました。あいつら制限時速も車と一緒だし、二段階右折を強要されることもなく、それでいて渋滞の車の間をすいすい走り抜けていやがる。
悔しくて眠れませんでした。寝ましたけど。それからは、まるで中学生のようにバイクに乗りたい、なんとかして乗りたい、免許買えないかなあ、とか、そんなことばかり考えるようになってしまいました。でも、ぼくが勝手に自営業になったばかりで、うちにそんな余裕はありません。ますます悔しさが募ります。このままでは手当たり次第にバイカーを襲う妖怪に化けてしまいそうです。「バイクがほしいんだけど」ある日、思い切ってかみさんに相談してみました。「お金どうすんのよ」「どうしようもない」確かに、どうしようもありません。ない袖でスイングできないのですが、スイングしなけりゃ意味はないのです。ああ。すると、かみさんがいいことを思いつきました。入る金に変化がないのであれば、使う分をどうにかすればいいのです。
以前、何かの予防接種に上の子を連れて行ったとき、診療所の部屋から部屋へとせわしなく動き回りながら、オリックスのなんとかというピッチャーと飲みに行ったとか、そういうとりとめの無い話を滔々としゃべっていた近所の内科医のオフィスで、チャンピックスを処方されたのが8月の終わり頃でした。考える間もなく始めたので、家にはまだ3カートンもタバコが残っています。
始めてみると、期待していたような禁断症状もなく、二週目から完全に禁煙し、3回目の診察で呼気一酸化炭素が普通の人と同じになりました。最後は薬(チャンピックス)を飲むのもさぼりがちになり、今は「吸うことは出来るし、仕方がなければ別に吸ってもいいけど、別に吸わなくてもいい」という気分のまま、全く吸わないで生活しています。でも、今さら禁煙席に座るのって恥ずかしくて、ときどき喫煙室に座ったまま一服もせずにいることがあるとか、ある程度の時間を過ごすのであればスターバックスは喫煙できないから入らないという習慣が抜けなかったりします。他人の喫煙は全く気になりません。いいにおいだなと思うくらいです。今さら受動喫煙で文句をいえるような立場でもないし、喫煙はいい気分になることだと知っているので反対もしません。むしろ喘息でもないのにタバコを吸ったことがないなんて、お受験エリートみたいな歪んだ子供時代を過ごしたんじゃないかと疑わしく思うくらいです。
さて、肝心のバイクですが、子供の頃にそういうのに全く憧れなかったので、どんなバイクがいいのかさっぱりわかりません。レースに出る人でもないのにゴテゴテくっつけてるのは嫌いだな、とか、その程度の判断しかできません。おまけに免許も取っていません。なので、結果的にはまだタバコをやめただけになっています。調べていて驚いたのが、大型免許って今はすぐに取得することが可能なんですね。といっても教習所でそういうのを受け付けているところは少ないですが。とにかく、まあ、その、こんなことを延々と書いているのはちょっとむしゃくしゃすることがあったからなので、そろそろやめますが、最後に、タバコやめると太るよ。これほんと。
Popularity: 3% [?]
ぐっどうぃる博士の音ライブラリ








