View FrameworkにStateMachineを併用するのよさそう

State Machine は以前から知ってはいたけど実際に書いて動かしてこれはよいなと思ったのでそこで感じたことなどを残しておこうと思う。

以下は Vue.js と XState ( SCXML ) の言葉で書くけど、考え方は他のツールでも同じように使えるはず。

課題感

  • View の状態を data ( state ), props で引き回して管理するのは繊細だし、状態の変数と実際に表示に使う変数が分かれたりしてこれらの変数は増えがち
  • 変数が直接 data ( state ) にあると jQuery 的にゴリゴリ data を書き換える誘惑に勝つのは難しく、Reactive ではなくなりやすい
    • この data を書き換えた影響をちゃんとハンドリングする component の実装が揃わないと UI のコーディングをブロックしてしまう
  • View component はそもそも複雑なオブジェクトでツリーの親子関係など暗黙的な依存もあり、テストコードを書くのが億劫になりやすい
  • では Store かというと変数が増えて繊細という問題は解消しないし、オブジェクトの Life Cycle への対応を自前で実装しないと無限に state が増える危険性もある

StateMachineとは何か

StateMachine は状態のパターンとその遷移に繋がるイベント、条件、ロジックのモデルであり、この State Machine を実現するライブラリはいわゆる DSL である。ストレージや何らかのフレームワークには依存しない。

とりあえず WikiPedia 貼っとく。

SdlStateMachine - 有限オートマトン - Wikipedia

いったんふーんと思ってもらえればおっけー。

StateMachineで何を解決できるか

例えば複数の状態を持ち、ユーザーの入力(イベント)に対して状態ごとに反応を変える、といった処理を作るとする。

フォームの送信なら 1) 送信可能な状態、2) 送信中の状態、3) 送信完了の状態があり、送信の操作に反応するのは 1 の状態の時だけである。2 と 3 では送信の操作に反応してはいけない。

これの実装は最も素朴には送信 handler の中で状態を見て分岐する形になるだろう。条件や状態が増えたらこの if 文がどんどん複雑怪奇になっていくパターンだ。

もう一つは 2 の状態になったら event listener を無効化する、あるいは event listener をセットしていない component にまるごと切り替えてしまう方法。こうすれば handler の中で if で分岐する必要はなくなる。状態と component が 1:1 になれば複雑さを解消できる。

では、表現は変わらないが内部の状態が変わるものはどうなるか。送信中の状態で送信ボタンの表現を切り替えずに別なところにインジケータのようなものを表示するような UI もあり得る。その場合は component の切り替えはできないので、click イベントを拾ったら handler で条件分岐する必要が出てくる。1

StateMachine を使えばこういう UI の表現やそれを実現するための component の階層に依存せずに状態を定義し、反応するアクション(イベント)とそれに対応する遷移先の状態を記述することができる。状態ごとに有効な入力をあらかじめ定義するので、入力を受け取って分岐する処理で頭を悩ませる必要がない。

そして状態の管理を component から StateMachine に移譲してしまうので、それぞれの状態や遷移時に行う処理が増えても、状態の数が変わらないのであれば View component 側で対応しなければいけないことは増えない2。例えばフォームの送信処理の際に storage に何かを記録するとか、同時に Google Analytics のようなものに何かを送信するとか。そういった変更が入っても component 側は頑張る必要がない。

まとめると、以下のようになる。

View component 側から見ると、具体的で詳細な処理や、依存する component の実装が進まなくても StateMachine があれば UI を組むことができ、処理の詳細に変更が入っても気にする必要がない。

StateMachine 側から見ても同じことが言える。component の設計が決まらなくても component に依存せず StateMachine だけを先行してテスト、実装できる。また状態に名前を付けなければいけないので共通認識を作りやすく、テストコードも書きやすくなる。

またあえて上では書かなかったが、タイマーの絡む条件があったりそのタイマーの処理をキャンセルするなどが入ると、生々しく書くのは煩雑でバグが入り込みやすいので StateMachine 自体が持っているタイマー関係の機能に依存してしまう方がよいと思う。

StateMachineでは何を解決できないか

StateMachine はあくまで状態の定義を行うためのもので、そこに State 以外のストレージ読み書きや通信などの処理は入れにくいし、入れない方がよい。

つまり、StateMachine を追加しつつ component を具体的な処理から独立した単なる Reactive な UI のままにするためには、

  1. View component
  2. StateMachine
  3. 1 と 2 を繋ぐ人
  4. より詳細な処理(より複雑なロジックや storage や network の I/O を担う人)

が必要になる。特に 3 の繋ぐ人が重要になる3

StateMachine を入れることで UI の実装自体を早くすることはできるが、一方で見て分かる通り 登場するクラスやオブジェクトは増え、それぞれのテストなどのコストは減らない。あくまでお互いにブロックしにくくなるというだけで、トータルのコストが下がるかどうかは一概に言えない。

個人的には View component か Store の二択で頑張るよりははるかにテストしやすかったので、コードを読み書きするコストはともかく、手動で確認しなくてもだいぶ安心して進めることができたという意味では、心理的なコストはだいぶ下がっていると思う。なんだけど、目に見えるコスト(実装完了までの工数)だけが最優先課題であるならそれを StateMachine で解決することはできないかもしれない。

また View Framework に限った話にはなるが、component が消えると StateMachine が消えてしまうので、どこに紐づけるべきかは考える必要はある。

まとめ

View component や Store だけで頑張るのはやめて、適切に Plain Old Object を使うレイヤーを差し込むとよいぞ。UI の表現の都合からくる component 階層の変更に強くなる。たぶんこれを Interactor と呼ぶとよいはずだ。

StateMachine は上の考え方の一例として分かりやすく効果的。特に状態が3つ以上あるとかタイマーが絡む場合は非常に管理しやすくなる。

State に応じた詳細で複雑な処理(外部 API を叩くとか)がある場合はそこも分けてしまおう。そいつは周辺の詳細であり、component とか store と一緒に最初に挙げた Interactor に DI しよう。Clean Architecture だ。

おまけ

今回具体的には

を使って UI の実装とは独立して並行で StateMachine から TDD で作ったんだけど、控えめに言って最高に快適だった。XState の書き方に慣れるまでがいちばん時間掛かったけど、そこは次回以降に期待。

  1. そこで Container / Presentational Component 分離してればまた違うかもだけど 

  2. それを component 側に書かないようにしてしまえば 

  3. ここは純粋なロジックと制御の世界なので Plain Old Object で書くとよい 

10.6のsipsは日本語フォルダ非対応

まとめ

OSX日本語フォルダ
10.7OK
10.6NG

10.6 の sips はファイル名だけなら日本語ファイル名でも ok なんだけど、フォルダ名に日本語が入るとダメ。

なんでsips ?

ImageMagick も psd に一応対応してるんだけど、やっぱり比較的最近の Photoshop で作ったちょっと凝ったものになると再現性に難がある。

Mac には sips があり、これの方が対応はいい。

ということで試そうとしたらがっつり日本語フォルダ名を使いまくられてて 10.6 環境で詰みましたとさ。

ようやく Rails3 アプリを一つリリースした。

リリースしたものよりもそこに至る過程や理由が自分にとって大事なのでそれを残しておこうと思う。

※ なんかこれしか書いてないとリリースしたものがどうでもいいように聞こえるけど、そんなことないよ! 付き合い続ける気があるからこその Rails だもの。

Rails の採用に関して

オレフレームワークとの決別と人材採用のコストダウン

これまで、PHP 4.2 以降で使えるオレライブラリ、オレフレームワークで小規模なものを作ったり、PHP 3 時代からのレガシーというか遺跡級のシステムの漸進的リプレイスなどを行っていたが、どうも限界を感じていた。なんか仕事が後ろ向きな感じもしていた。このままだとずっと時代に追いつけずに終わりそうという危機感もあった。

また、Google App Engine の登場以降感じていた「うちに必要な技術はこれだよ」と具体的にはっきり言えること、それによって生み出すことのできる人材の流動性を取り入れたいと思っていた。正直「PHP と MySQL が使えること」なんて何の指標にもならない。だからやるならメジャーで、かつまだ自分で勉強する気のある人を見分けられるフレームワークが良いと思っていた。幸い日本ではまだ Ruby や Rails はそれほど定着し切っていない。東京はともかく田舎では Ruby を書ける人は多くない。それでいて情報量は多い。もちろん英語。それがまたよい。

また適度に「枯れない」具合が Web サービスの構築にも向いている。この世界は様々なレイヤーで常識が簡単に変わる。枯れすぎていてはいけない。

そしてこの枯れない技術にキャッチアップしている人を採れば少なくとも外れはないだろうし、逆にそういう技術を採用している会社だとアピールすれば、優れた技術者にそっぽを向かれないだろう。お互いにデメリットはないはずだ。「適切なバージョン管理システムを用い、Railsなどのフレームワーク1でテスト駆動開発ができる人」が欲しいし、ユーザー企業としてはこれを実現してくれる会社に仕事をお願いしたい。

もう一つ、自分のウリにもなる。

Rails 3 がよさげだった

それまでの自分と Rails の関係はと言えば、Rails 1 の頃はついていけず、2 の頃は設計の無理矢理感や Rail からの外れにくさなどのネガティブな話をよく聞くようになったので「待っていた」。

ただ、Rails 1 で登場した ActiveRecord の migration は本当に欲しいと思っていた。DB もコードと同期が取れる。テキストで管理して漸進的に開発を進められる。まだアジャイルなプラクティスが身にしみていなかった頃でさえこの言葉は自分に突き刺さった。今も刺さったままだ。だから Rails のコピーのくせにテストのサポートもなければ migration もない CakePHP には心底頭にきた2し、いつか必ず Rails が仕事の助けになると確信していた。

Rails 3 は本当によさそうだった。

  1. Merb と統合してフレームワーク自体が疎結合になる
  2. 全面的に rack ベースになる

特に 1 についてはオレフレームワークでも密結合のダメさを痛感していた。それもあって Rails 1, 2 の頃はやはり躊躇した。

rack も注目していた技術なのでとても嬉しかった。plugin の実装が Rails 独自のものでなくなるのでライブラリがさらに充実するだろうし、特にこれで完璧に開発環境と production 環境の切り替えがスムーズになったと思った。

実際には bundler のスゴさをのちに思い知ることになるんだけど。

タイミングが良かった

Rails 3 の採用は少し賭けだったが、

  • サービスの形が見出せずに打ち合わせの期間がだいぶ長引いた
  • そうこうしているうちに Rails 3 が正式にリリースされた
  • 当初は適当なブログエンジンや CMS をカスタマイズする気でいたのだが、本心ではそういう仕事のやり方を望んでいた訳ではなかったので、一気に方針を切り替えた

正直、話が順調に進んで Rails 3 が beta の頃に Go が出ていたら採用はしていなかったと思う。それくらい自分は stable 志向だ。それに Rails の経験もなかったし。

もう一つは Ruby Enterprise Edition が 1.8.7 になっていたこと、さらに古い 1.8.5 で動いていたシステムを停止するタイミングが重なったことも大きい。テストの工数をばっさり削れた。

はっきり言って幸運だったとは思うが、REE も rvm も 1.8.5 ベースのシステムのチェックも怠らなかった積み重ねだとも思っている。

cf.

Ruby のオープンクラスと github とコミュニティを信じていた

PHP と Ruby を最もよく書いたのでこの二つの比較になってしまうが、やはり自分の中で Ruby の最後の良さは

オープンクラスであり、好きなようにモンキーパッチを書けること

だと思う。

これと、自分の中にあった Ruby に対する小さな自信が

ライブラリにバグがあった場合 PHP だと逃げようがなくても、Ruby ならなんとかなるし、大丈夫

という形で Rails 3 の採用を後押ししたし、様々なライブラリを試し、コードを書き始めてからも安心に繋がっていた。

実はこれまで何度か PHP のライブラリでは痛い目に遭っている。

  1. class の名前被りは fatal error で強制終了のクセにちゃんと pear パッケージ化して名前空間の譲り合いをしない
  2. リポジトリが svn ( or cvs )
    • 作者が放置しててパッチ取り込んでくれない

これが Ruby なら

  1. フツー gem だし名前の衝突で訳の分からないことにはならない
  2. リポジトリはフツー github なので最悪作者が放置してても fork して直せばいい
    • 自分でやらなくてもだいたい他の人がそれをすでにやってくれている
  3. 最後はモンキーパッチで逃げられる

これだけ有利な条件が揃っていて Ruby を使わないなんてどうかしてる。

結局今回はモンキーパッチで逃げ続けたものはない。最終的にはライブラリの方に吸収されて自分のパッチは捨てることができた。コミュニティが生きている感じがとても嬉しかった。

cf.

新しく取り組んだこと

基本はイテレーティブに

スクラム的にデモを重視し、定期的にデモとミーティングを重ねた。イテレーティブに進めること自体は今までも勝手に取り組んでおり、この期間でこれくらい、という見当は小さいものならついていたが、今回は今までの経験よりだいぶ大きなものになったので、イテレーティブな取り組みそのものにプロダクトオーナー(と、勝手に想定)を巻き込んでデモをするところまで行った。

結果、前半は見た目(デザイン)が追いついてこないので付き合わされる側は退屈だったようだ。

しかし自分にとっては「きついがとても良いリズム」ができたと思う。デモを木曜日に設定したのも良かった。

RSpec で TDD

テストの支援をまともにしてくれるフレームワークなんだからやらない方が嘘。本格的に使うのは初めてだが3レポートの読みやすい RSpec を採用した。中身(バックエンド)は一人でやるので時間さえ都合がつけばなんとかなるはずだった。一部 Rails + RSpec の考え方を自分が飲み込めなかったり、単にテストしにくい部分(条件に応じて変わるメールの文面とか)もあったが、まずまずの状態にはなったように思う。

ただし jQuery を使った DOM をいじる処理にテストは書かなかった。Jasmine を使って TDD を回すことはできたはずだが、初めてのことが多くなりすぎるとしんどいので JavaScript については手を抜いた。

ちなみにリンクを張るために漁っていたのだけど、自分が RSpec で BDD だぜひゃっはーと最初に感極まったのは2008年2月の RubySapporo だったことを思い出した。やる気のない土曜出勤の中「あーこれからはこれだな」と確信したのを覚えている。

ただ、このとき感じた「Ustすげぇ」は今は薄れている。このときは Ust で伝わったことの中にほとんどすべての価値があったが、今は Ust で伝わらないことの中に価値を見出そうとしている。

cf.

Fabrication でテストデータ生成

デモを重ねてプロダクトコードが変わるたびにテストデータを作り直すだろうことは最初から分かっていたので、テストデータ生成ツールにまず取り込んだ。

厳密には今回初めて取り組んだことではないが、作ったデータを seed で取り込める形に出力するなどの細かい機能改善をくり返した。

また、標準の Rails では意外に seed や fixture の扱いが良くないということがだんだん分かってきた。

cf.

RR で stub out

RSpec に RR を組み合わせてテストしにくい部分の stub out を行った。

今回改めて考えさせられたのは

今自分は何をテストしているのか

を考え続けることの大切さだった。何をテストしているのかが分かっていないと何を stub out してよいかが分からない。stub や mock という言葉だけ知っていてもこうしたツールはまったく使いこなせない。使い方が分かることと使えることの違いがものすごく大きなツールの一つだなと痛感した。

cf.

Capistrano で deploy

Capistrano の記事を最初に書いて2年半経っているが、ようやくこれを実現できた。これで手作業の転送で意図したファイルを転送し忘れたとか、余計なファイルを上げてしまったとかそういう事故は起きなくなった。TDD の安心感も絶大だが、deploy ツールの安心感もすごい。

checkout 元になる repository が svn で、これが LAN 内にあるので production 環境にどうやって持っていこうかと思ったが、svnsync を使って production 環境のあるサーバに持っていくことにした。

たぶん svnsync を試そうと思ったのはこのことが頭にあったからなんだと思う。確かそう。

cf.

管理画面のTypusのviewに手を加えないためにJSを使った

管理画面は全面的に Typus を採用した。初期の頃はやりたいこともシンプルだったので CSS の調整だけで済むかと思ったが、徐々に扱いにくさを感じてきた。しかし View に手を出し始めると、アップデートの際に構造が変わってたらやっかい。そこで

Url Dispacther を応用して特定のモデルに対する編集作業のときの画面の DOM を JS でいじる

ことにした。

これが見事にハマった。いい意味で。例えば google map のプレビュー機能とかそういう機能が欲しくなるんだけど、直接 View をいじらずに JS だけで後からその機能を追加することができるのはとても助かる。

これを知った当初はこんな風に使えるとは思ってなかったけど、JS だけでゴリゴリいけるのは JS の分かる人間だけで作っていく際にはとても便利だなと感じた。

cf.

git を基本にした

中央のリポジトリは svn なのだが、それの置き換えはともかく、今回は自身の git 経験をさらに伸ばす良い機会と捉えた。これまでは git + svn 両刀で git は master branch だけを使い、ある程度成果が出た段階で手作業で svn にも反映するという方法だった。

しかし今回は svn 上のコードのないゼロからのスタートなので最初から git で管理し、小さなストーリーくらいの単位で git の branch を切って作業した。

また当初は git-svn は使わなかった。というのも開発初期から中期に掛けては migration やコードの書き直しが多くなりすぎるし、これら全部を後から参照する必要はなかったので、ある程度の区切りがつくまで git だけで管理し、最終的には履歴を捨てて svn に突っ込んだ。

git-svn で svn と同期を始めてからは rebase や cherry-pick にも積極的に取り組んだ。svn にはできるだけきれいな commit log を残しつつ git 上には頻繁に commit をして後からどうにかなるようにしておくことを心がけた。

ハマったこと

seed とか fixture とか支援なさすぎ

意外なことに seed データや fixture について Rails はかなりあっさりしていた。seed データの生成支援も読み込み支援もなかった。読み込み用のツールを書いた。fixture の書き方の注意点も rails guide や普通の参考書籍では分からなかった。全部自分でハマってメモを書いた。

Typus がビミョー

Rails 3 になって 2 時代の管理画面用のライブラリが軒並み使えなくなった。Typus を採用したが、Typus の仕様なのか自分で Rails を使ったモデリングを分かっていないせいなのか分からない、不具合というか期待と違う動作に苦しんだ。

基本的にはよくできてると思うんだけど、いかんせん Typus については情報不足でやられた感が強い。今となってはボクは日本人としてはだいぶ Typus のクセをつかめてる方だと思う。

でも Rails 3.1 時代の標準にはならないんだよね? これ。たぶん。

新しく始めなかったこと

  • ユニットテストの自動化は 5 年以上前から行っている。ただ、これを支援してくれるフレームワークと組み合わせてやったのは初めて。
  • TDD はここ 1, 2 年くらいそこそこ真面目にやっている。
  • Selenium IDE による自動テストはいつ始めたか覚えてない。Selenium Core を使ってブラウザ依存を排除するようになったのは 1 年前だけど今回はあまり一生懸命 Selenium は使っていない。RSpec を中心にした。
  • git は 3 年くらい前から使っている。bundle ファイルはよくバックアップ代わりに使っていたが、branch や rebase, cherry-pick, stash などは使っていなかった。
  • svn によるバージョン管理は 6 年くらい行っている。と思う。(その前はCVS)
  • Trac での課題管理は 5 年以上行っている。使い方は徐々に変わってきているけど、今回もイテレーションを Trac の milestone に当てはめて作業を設計している。ただしきっちり timebox を守ったイテレーションにはできていない。短い期間や長い期間ができている。
  • Ruby は何年使ってるか覚えていない。Web アプリは古式ゆかしい CGI を除けば初めて書いた。

テストや deploy を手作業で行う弊害はずっと感じていたので、その辺の取り組みは今に始まったことではないし、そこそこ準備できていたと思う。

できなかったこと

  • Continuous Integration
  • Cucumber
  • Selenium の安定した(いちいち変更しない)テスト
  • デザイナとのクリエイティブな共同作業

まとめ

みたいなものはないよ。

あえて書くとすると、しんどかったけど、いろいろ好条件にも恵まれたなと思う。契約の絡むややこしい相手に対して 1 〜 2 週間に 1 回デモをやるというのは日本の、というか少なくともこの辺の田舎のビジネスではちょっと厳しいような気がする。社内だけで済むからこそできただろうことももちろんある。仕様を大真面目に議論してお互いの納得を作ったり、仕様の変更、追加を理由に期間を延ばしたり。そのために最初に締め切りだけを切るのはやめよう、という提案も通した。これくらいからこれくらいの期間に終わる、という予想を出し続けた。

またしんどいって言っても謎のバグが取れないとかそういうしんどさではなく、単なる作業時間の読みのずれ4だったので、「頑張ればなんとかなる」レベル。

プロジェクト自体の参加者は複数人いたが設計も実装も一人で行えたことも実は大きい。自分以外の人を教育する必要がないから。ただ、仕様をレビューしてくれる人もいないので大きな不安は残った。まぁだからこその変更に強い仕組みでもあるんだけど、このままの体制はダメだなと改めて思った。

ただ、少し自信がついた。ボクは20世紀プログラマを卒業できたかな。

  1. 上の意図が実現できれば、この点に関しては別に Rails でなくたってよい。あえて言うと Rails は考え方のハードルはあっても環境構築や実装作業そのものについてはそれほど難しいものはないと思うし、「作法に従いやすい」ツールだと思う(ポリシーがはっきりしている)ので、そういう意味でオススメするけど。 

  2. 後発がオリジナルより遅れててどうする。もちろん当時のバージョンの話で、今は調べてないので分からないけど。 

  3. TDDBCで経験自体はある 

  4. 作業があとから膨らんだケースはそんなになかったし、あったとしても予想よりすぐに対応できた。これが本当にレガシーなものだと膨らんだ先のボリュームが全然読めなかったり、2次被害3次被害が発生したりするもんだけど。 

最近の Windows に deltree はない

むかしむかしあるところに DOS プロンプトであるディレクトリ以下全部削除したい男がおったそうな。男は

deltree DIR

を使っておったそうじゃ。

……。

今ね、deltree ってないんですよ。どうするかというと

rmdir /s

で対応する。

15:47:23 >wtnabe< 4/6 に finalfusion たんに教えてもらったけど fav り忘
                  れていたこと。deltree がなかったら rd /s すればいいじゃ
                  ない。デリー・ト・シタイノヨット

rm を再帰的にやるのではなく、rmdir を中身が空じゃなくても問答無用で行うオプションを付ける。ふーむ。

DENIMもう一度試す

Web サイトの手書き風プロトタイピングツールとして DENIM が(一部で)話題になったのっていつだっけ。

DUB - DENIM

OSX 10.2 以降で動くのに JRE 1.5 を要求するというのはなんか変じゃないかと思うけど、Java がないと動かない。Windows で使う分には Java のバージョンで困ることはないやね。

06:31:24 >wtnabe< もしかして DENIM ってオブジェクトの移動できんのか。ほ
                  んとに手書きと同じじゃないか。
06:38:01 >wtnabe< cut & paste はできるけど移動ができないと厳しいなぁ。
                  もう頭が完全にドローツール向けになってる。
06:49:19 >wtnabe< cut & paste はページそのものならできるけど、オブジェ
                  クトは消して書き直す感じっぽいな
06:53:06 >wtnabe< イメージとしてはちゃんとサイトの概念やアクションを気
                  にする人同士の会話には使えそう。見た目重視の人には使
                  えないって感じか。あと当然画面が小さいとかペンタブレッ
                  トじゃないとかも使いにくくなる要因かな。
07:57:32 >wtnabe< DENIM のサイトはなんで port 2007 なんだろう。ただのシャ
                  レならやめてほしい。fw に引っかかる。
08:03:19 >wtnabe< なんか java のダウンロードが訳が分からなくなってる。
                  なんだこれ。

実際に使ってみないと伝わりにくいけど、

  • ページの並びは cut & paste で移動できる
  • ページ内のオブジェクトは消して描き直すしかない

ということで、手書き風って見た目が手書き風なだけじゃないんだ。

ページ間のリンクが意外に細かく制御でき1、独自のブラウザも搭載していて見た目はともかく構造と機能を考えるには十分使える。

ただ操作性はかなり独特なので好みは分かれると思う。あんまり独特で最初は Java じゃなくて Squeak か何かと思った。普通の UI パーツを使うタイプのプロタイピングツールは、見た目はともかく構造の記述ができない場合が多く、両方のいいとこ取りをした本気のプロトタイピングツールがあれば結構売れるんじゃないかなぁ。それくらい現状は中途半端な印象。

  1. 例えばフォームの正常遷移と異常遷移を記述できたりする。 

今さらRTM

Remember The Milk

外出の機会が増えるらしいので、スケジュール管理はイントラの ics ファイル + Thunderbird + Lightning だけではまかないきれんなぁと思い、久しぶりに Remember the Milk でも使うかーと思って昔の情報をひっくり返してみた。

Google Gears + RTM - あーありがち (2007-06-09)

おぉ。なんと Remember the Milk のアカウントは2年間塩漬けにしていた。

09:05:32 >wtnabe< rtm って日本のフツーのケータイで使えるんだっけ
09:07:24 >wtnabe< おぉ。RTMは2年間塩漬けだw
09:55:41 >wtnabe< んー? RTM のリマインダが来ないな
10:25:21 >wtnabe< 今RTMってあんま流行んないんだっけ?

あれこれ試行錯誤したけど、最終的にこんな感じの設定になった。


RTMのリマインダ設定。

この設定で

  • タスクのある日の朝7時
  • タスク期限に設定した(自分の感覚で言うと期限と言うより作業開始時刻)の15分前

にメールが来るようになった。あれこれ設定したけどケータイに飛ばすのがいちばんかなということで、今は RTM からのメールがいちばん多いという状態に。目覚まし忘れても、なんかある日には7時に何かしらのメールが来るので安心感も今までより大きい。


機能としては満足度は高いんだけど、どうも使い勝手はやっぱうーんて感じで、戸惑うこともまだ多い。

11:59:50 >wtnabe< あれ。うっかり ESC 押したら確認なしでタスク消えた?
12:00:36 >wtnabe< マジか。信じられん。ものすごい脆弱性じゃないか。
12:01:18 >wtnabe< 元に戻せた。それにしたってなんだおい。

[追記] 「場所」は登録されている場所しか記入できないのでちょっと面倒。しかも登録手順がよく分からずに戸惑った。

正解は地図の右側の場所リストの上にある「場所を追加する」を押してから地図上のポイントをクリックする。

なーるほどな。

cf. Twitter / wtnabe: あ、いけた。「場所を追加する」ってやってから地図をク …

user.js creator ってないんかな

あるいは Mozilla アプリのデフォルトの設定を変更する方法。この日の日記は実際には 7月10日に書いています。

Mozilla アプリで同じ設定をバラまきたい

Mozilla アプリの設定ダイアログとか about:config で「デフォルトから変更したものだけ」を抽出して user.js に書き出してくれるものってないかなぁ。

何に使うかというと、

同じ設定の Mozilla アプリを大量に deploy したい

っちゅーことなんですが。prefs.js 直書きしてってもいいんだけど、できれば設定変更してほしくないものを user.js の方に書いておきたいということで、その特定の設定だけ user.js に書き出してほしいわけ。もしくはアカウントごとの設定の部分なんかもうまい具合にスクリプトとかで対処できるといいな。つかスクリプト書けってか。うーん。Mozilla の profile データの扱いを wrap してくれるライブラリがほしいな。

というかそもそも、prefs.js や user.js を使う以外にいい方法あるのかな? Mozilla.org な人たちには何かノウハウあるんやろか。

Mozilla の環境設定への簡単なガイド

システム管理者はもうひとつの方法として user.js ファイルを app_dir/defaults/profile/ に置くことができます;こうすると user.js のコピーを新しいプロファイル全てに置くことになります。 この方法には、スタートアップのたびに環境設定をシステム管理者によって設定された デフォルトにリセットできるという利点があります。それには注意が必要です。 通常ユーザは自分のプロファイル・ディレクトリにアクセスする権限をもっているので、 方法を知っていればデフォルト値を変更できるのです。 もう一つ不利な点としては、既存のプロファイルには効果がないことが挙げられます。

ほっほー。これならユーザーが変わって新しくプロファイルを作るときにもデフォルトの値が反映される。これはいいな。

あとはできるだけ楽に user.js を作成する方法と、アカウントごとの設定を「うまい具合1」にする方法が分かればいいんだな。後者は結構難しそうだけど。

例えばアカウント独自の設定項目について、どのアカウントでもこの設定にしたい、っていうのをサクッと実現するにはどうしたらいいんだろ?

mail.identity.default.*

こんな設定項目があるな。これか。これっぽいな。

ついでに、

mozdev.org - mozptch: index

なんてものも見つけたけど、基本的に Windows でしか動かないし、どうも思っていたものと違うような気がする。というか最初の入力以降はうまく動かなかったんだけど。

実際にやってみた

今回やりたかったのは Thunderbird. HTML メールを送るなとか、開封確認に答えるなとか、そういう設定を毎回やるのは面倒なので、デフォルトを書き換えようと思い立った。散々探したけど便利ツールはないっぽいので、

Thunderbird Help: プロファイルの管理

を参考2に、地味に

  1. 2つ新しいプロファイルを作って
  2. 片方を好みの設定に変更し
  3. prefs.js の diff を取ってコピペ、必要ならオリジナルの設定項目名 .*\.default\..* などを推測

という方法になりました。user.js で固定しなくてもよい項目もあったので、

defaults
|-- pref
|   `-- all.js   ← prefs.js になる
`-- profile
    `-- user.js

に書いたところ、予想通りに反映されるようになりました。spam の設定はヘッダを利用する項目がサーバの方にあるらしく、

  • mail.identify.default.*
  • mail.server.default.*

の辺りに書いておくといろいろ楽になるようです。奥が深い。ただ、当初の予想に反してスクリプトはまず書かなくてもいいので、そこはよかった。

  1. いいが 

  2. OSX は option + ダブルクリックではなかったけれど、thunderbird-bin -p でも thunderbird-bin -profilemanager でもイケた。 

OS X アプリメモ

  • ircle は日本語の扱いがダメ。
  • Gecko エンジンのブラウザだとボタンやフォームなどで妙に文字の下の感覚が広い(Safari は問題ない)

今こそ我が身が自由であれば

美川特区アットマーク国際高校

だそうで。なんつー間の悪さかね。

アットマークハイスクールの方法に全面的に賛成するつもりもないが、今の自分にはそうした意見や考えを現場にフィードバックする方法がない。

その場に自分が居ることができないという現実はやはり少し身にしみるものがある。

Mozilla 関係のアップデート

shell: プロトコルセキュリティ問題について Mozilla ユーザが知っておくべきこと

XPI のインストールだけで問題解決できる。config いじるだけですが。

わざわざ 1.7.1. 0.9.2 などに上げるまでもなかろう。

データベースが必要なのは i-mode のみ

携帯対応のサイトを作る際に問題になるのは

  • どのレベルの HTML に対応しているのか
  • 使える画像はどんなものか
  • 画面のサイズはどうか

というのがいちばん基本的な部分だ。(Java だのマルチメディア関係はとりあえず置いておく。)基本的には全部調べて何が使えて何が使えないのかを把握することが最初にやるべき仕事で、そのあとに機種によって微妙に違う部分にどう対処するかを考える。考えるためにはまずアクセスしている機種の情報を知る必要がある。これを知る方法だが

  • Vodafone live! も EZweb も HTTP の独自拡張ヘッダに情報が入る

ので、

  1. 独自に DB を用意して
  2. UA から端末を識別し
  3. その端末の性能を調べて対応する

という面倒な儀式が必要なのは i-mode だけである。

この殿様将軍様 DoCoMo 様めぃっ。

なので、端末情報取得クラスを一つ用意し、Vodafone live!, EZweb の場合は独自拡張ヘッダから情報を取得、i-mode の場合は自前 DB を参照、という具合に処理を分けてそれを隠蔽してやれば、使いやすいものができると思う。

About

例によって個人のなんちゃらです