MacからDELLのディスプレイにきれいに画面を出力させる方法

MacでMini DisplayportからDELLのディスプレイに画面を出すと、とても汚いことがあります。これを直す方法。僕はU2713Hで気づきましたが、U2713HMとかU2711とかでも同じ問題が発生しているはずだし、他のディスプレイでも同じことが起きているかもしれない。

tl;dr

上のURLから、patch-edid.rbをダウンロードして実行すると、DisplayVendorID-10acみたいなディレクトリがすぐ下にできるので、それを/System/Library/Displays/Overridesにコピーして再起動する。再起動すると、DELLのディスプレイがちゃんと良い感じに表示されるようになっている。

私になにがおきたのか

DELLのU2713Hというディスプレイを買って、昨日無事に届いて、Macに接続したらすごい汚い表示で愕然とした、というのが発生した現象。シャープネスを強くするフィルタをかけたような表示。ディスプレイにはシャープネスを設定する機能があるので、それを初期値50を0にすると、まあなんとなくまともになった。

とりあえず、社内のMac何台かで試したけど、同じ表示だったので、初期不良を疑って、DELLに電話して、交換品を届けてもらったのが今朝。

Macにつないでみると、やっぱり汚い。念のため、Windowsにつないでみると普通にきれいに表示されている。これはおかしい。

というわけで、上のURLを見て、良い感じになったという話でした。DELLのディスプレイでも、U2713HMとU2711は、そこまで汚くなかったので、気づいていなかった。同じ問題は発生しているはずなので、試しにU2711のもRGBにしてみたけど、これできれいになったのかというとよくわからない……

さっきのURLの話の要約

  1. なんかわからんけど、DELLのディスプレイをMacでMini Displayportでつなぐとすごい汚い
  2. これはYCbCrというモードになってるからで、これをRGBにするべきである
  3. RGBにするには、なんか設定ファイルをアレすると良い
  4. U2713Hのやつはこれだぜー
  5. (ちょっと後で)このRubyスクリプトを実行すると、接続されてるディスプレイのパッチを作るようにしたよ!

開発のスループットを犠牲にしてレイテンシを向上させる

アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~

アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~

ソフトウェア製品の一部をまず完成させる。次に、別の一部を完成させる。もう一つ、別の一部を完成させる。こういうやり方を続けていくと、最初のほうに作った部分と最近になって作った部分のコードは、かなり違ったものになってしまう。最近になって必要になったモデルの機能は、最初のほうに書いたコードのデザインとうまく一体化していない。そこで、全体を直す作業が必要になる。これをリファクタリングと言う。一つ機能を追加するたびにリファクタリングする必要があるので、当然、開発のスループットは落ちる。それでも、一部ずつソフトウェアができあがっていくので、進捗を開発者以外とも共有しやすいし、できてから初めて気づいた問題にも素早く対処できる。実は必要がなかった機能を実装してしまう可能性は、少なくなる。スループットが落ちる代わりに、ソフトウェアの価値が発生し始めるまでのレイテンシは短い。

最初に全部を見渡して完璧な設計を導出できるなら、リファクタリングは必要がない。リファクタリングに必要な時間がいらなくなるので、スループットは向上する。一方で、完璧な設計にたどり着くまで、ソフトウェアの設計はなかなか進まない。レイテンシは悪化する。


もちろんビジネスの種類にはよるんだけど、ものすごいざっくりと言えば、原則としてスループットを捨ててレイテンシを取るほうが賢い戦略だと思う。少なくとも僕が生きている自分で適当なWebサービスを開発するような世界では、レイテンシ向上をデフォルトの戦略にするのが良いと思う。

ただし、当然だけど例外があって、レイテンシの向上でもたらせる利益によって帳消しにできないくらいにスループットの低下が激しい場合には、後者の戦略のほうが正しい。

レイテンシの向上が利益をもたらさないのはどういう場合かというと、スコープと期間があらかじめ厳密に定められていて、変更ができない場合である。スループットの低下が無視できないくらい大きいのはどういう場合かというと、リファクタリング(に相当する作業)のコストが大きい場合である。例えば、よく知らないけどハードウェアの開発とかそれに関するものとかだときっと大変でしょうね。

僕の感想だけど、どっちの条件についても緩和される方向に、人類が進化するのが正しいと思う。

inputでエンターキーを押しても、formのsubmitイベントが発生しないのはどうすれば良いの?

いつも忘れて混乱するので書いておく。細かいルールを解説したページを前見たんだけど見つけられない……

formの中にinput[type=submit]なinput要素がないと、テキストフィールドでエンターを押してもsubmitイベントが発生しない。見えないようにしたsubmitボタンを、

<input type="submit" style="float:left; opacity:0; height:1px; width:1px; margin:0" value="to fire submit event on enter">

とでも書いて、設置しておく。display:noneだと、やっぱりsubmitイベントが発生しない。


でこの辺に悩んだ結果「Enterキーが押されたらsubmit」とかやると、日本語変換の確定とかの思わぬタイミングでsubmitされて悲しい思いをすることになる。まあ日本人ならちょっと触った時点で気づくだろうから、ここに書いてもしょうがないだろうけど。アメリカ人は最後まで気づかないんだと思う。例:Pivotal TrackerのTask欄。

テキストフィールドの値の変更の監視にはkeyupイベントではなくてinputイベントを使おう

漢字が読めないがいこくじんやようちえんじにもひらがなならよめるね!アクセシブル!

という話ではなくて、keyupイベントを使ってテキストフィールドの変更を監視するとiOSでこんなことになります(多分、変換の確定がキーイベントじゃない)。左上の「かんじ」は本当は「漢字」になっててほしかった。(ちなみにコピペしたときも更新されずに問題が起きます。)

inputイベントを使うとこういう問題は発生しません。

先ほど指摘されましたので、ユビレジのkeyupはすべてinputに置き換わりました。漏れはないはず。

ユビレジで水が飲めるようになるまでの話

水が飲めるようになるまでの例え話にだけ食いついてみる。まあタイトルはちょっと嘘で「お菓子を食べられるようになるまで」の話ですけどね。

ユビレジは、2010年に始めたスタートアップです。現在のスタッフは10名で、まあ今のところ不自由なくオフィスで作業中にお菓子をつまむことができています。この体制を確立するまでの経緯で、その中に権限の委譲に相当するものがあったのか、ちょっと考えてみたい。

一番最初:手の空いてる人がお菓子を買いに行っていた時代

最初は、お菓子の買い出しは社長の木戸の仕事でした。木戸と私しかいない時代のことです。このときは、別に私がお菓子を買いに行くのをすごいいやがったとか、私がたまにお菓子を買い出しに行くと木戸の嫌いなものしか買ってこないとか、そういう事情ではなくて、Webサービスを作るようなスタートアップの場合、最初は(ソフトウェア開発ができない)人ってお菓子の買い出しくらいしかやることがないのよね……という状況。*1

僕が黙々とお菓子を食べながら開発をして、木戸が唯々諾々とお菓子の買い出しに行ってました。

この体制の問題は……そんなにないな。まあ暇な人が暇なときに買い出しに行くという体制なので、忙しいとお菓子がなくなるという問題があります。でも忙しいときは近所のコンビニでうまい棒買ってくればそれで良いよね。

まとめ
  • 暇な人が暇なときに買いに行く
  • 二人とかの体制だと特に問題はない

東京に出てきてから:渋谷のドンキホーテに木戸がお菓子を買いに行っていた時代

上と変わらないので省略

権限の委譲1:僕がドンキホーテにお菓子を買いに行っていた時代

さて、このころ何があったかというと、

  • オフィスの分割:開発チームとセールスチームで別々の拠点になりました
  • 会社のクレジットカードを作って、木戸と僕が持つようになった

という二つがありました。あ、お菓子の文脈で言うと、ですからね。他にもありましたよ、人が増えたりとか。

木戸はセールスチームを指揮しているので、開発チームのオフィスにはお菓子がなくなりました。なくなったというか、まあほっといても補充されなくなった。

しょうが無いので、僕がお菓子を買いに行くことになりました。なぜ僕がお菓子を買いに行くかというと、僕は役員なのでどれだけ働いても給料が変わらないからです。これを社員の人にやってもらおうとすると、お菓子を買い出しに行く時間のお給料を払う必要があります。当然ですが、社員の人はユビレジの開発をしてもらうためにユビレジで仕事してもらっているので、そんなことに給料は払いたくありません。そこで払わないという手もあるとは思いますが、まあ道徳的にそういうのは避けるべきです。僕が買いに行っていました。

もう一つの僕が買い物に行く理由としては、精算をできるだけ簡単にすませたいというものがあります。僕は会社のカードを持っているので、そのカードで買い物をすればそれですみます。このカードを持っていない人が買い物をすると、領収書を持ってきてもらって、経費の申請をして、計算をして、振り込まなくてはいけません。まじめんどい(僕はやったことないけど)。

だいたい、2週間から1月に1回くらい、深夜にドンキホーテまでてくてく歩いて行って、お菓子を買って、帰ってきて、みんなで食べてました。ちなみに、お菓子は切れるとなかなか補充されません。なぜかというと僕が買いに行くのを忘れるから。仕事してたいよねー。

まとめ
  • 役員の報酬は定額なので、雑用はできるだけ役員にやらせるほうが(金銭的な面で)都合が良い
  • クレジットカードという支払いに関する権限が松本に委譲されたので、支払いができるようになった
  • 一度お菓子が切れると、松本が買い物に行く気になるまで補充されないので、お菓子なしの状態が続くことがあった

アスクルの活用

さて、お菓子がなかなか補充されない状態にぶち切れた開発チームのスタッフが、ある日こんなことを言い出します。「Amazon楽天でお菓子を買おう!」これはすばらしいアイディアです。ドンキまでてくてく片道20分かけて歩いて買いに行っていたことを考えると、インターネットで3回くらいクリックするだけでお菓子が届きます。IT革命です。

何度かお菓子を買いましたが、もっとよく考えてみると、そういうのに特化したサービスが世の中にはあります。アスクルです。

さっそくアカウントを作って、お菓子の買い物はアスクルで行われるようになりました。同時に、松本はお菓子の買い出しの職務から外されることになりました。なぜかというと、他にやることがあるので、どうしてもどんどん後回しになってしまい、お菓子不足に悩まされる期間が長く続く傾向にあったからです。ユビレジのお菓子係は、さらに年功序列の上位であることから、デザイナの宮内という子に引き継がれました。彼女は(松本に比べると)非常に几帳面で、お菓子が切れた状況が何週間も放置されることはなくなりました。

当初は、アスクルで注文するときにも、なんとなく私が相談されていたのですが、現在では完全に彼女が一人でお菓子の発注を担当しています。お菓子の発注という権限は、こうして完全に委譲されたのでした。

こうして、ユビレジではいつでもお菓子が食べられる体制を2年かけて確立したのでした。たかがお菓子といえども、なかなか苦労するものですね。いや苦労は特にしてないけど。時間はかかった。

まとめ
  • お菓子の買い出しを通販で行うというイノベーションが発生
  • これにより、買い出しにかかる時間が劇的に短縮され、役員の時間外の雑用から社員の業務(の一部)へと、買い出しが昇格
  • 安定したお菓子の供給が可能になった

結論

こうしてみてみると、まさに権限の委譲と呼ぶにふさわしい変遷をたどってきていることがわかります。お菓子を買うという、社長にのみ許された特権的な行為が、一般の取締役に開放され、現在は社員が行っています。あと1年もすれば「誰もやる人がいなかったので、できるだけ省力化できるように最適化を進めた」という記憶は失われ、きっと「お菓子の買い出し」がそれ自体で一つの権限として確立される日が来ることでしょう(来ない)。

でもこれって要するにめんどくさい雑用が合理的に押しつけられる先に流れていったとかいう話なので、なんかこうソフトウェア開発みたいな仕事とかスクラムがどうとかそういう文脈で話を出しても、なんか良くわからなくなるよなーとか思いました。

いつもの宣伝です

お菓子が安定して供給される体制を2年がかりで確立したユビレジでは、現在、求人を行っています。どうやら今は「事業開発担当者」とかを募集しているみたいです。ソフトウェアエンジニアではなさそうなことは推理できますが、具体的に何をする人なのか僕はあんまり良くわかってなかったりします。

興味がある方はメールをください。

*1:正確に言うと、木戸は渋谷に出稼ぎに行って僕の給料を稼いできていたので、ちゃんと仕事してましたが、サービスの開発という面ではまああんまりやることがなかったのは否定しにくいと思う。

テストが通らなくて5時間泣いた話をしようか

class MyError < StandardError
  attr_reader :exception
  def initialize(exn)
    @exception = exn
  end
end

begin
  begin
    1/0
  rescue ZeroDivisionError => exn
    raise MyError.new(exn)
  end
rescue MyError => exn
  p "rescue MyError", exn
rescue Exception => exn
  p "rescue Exception", exn
end

上みたいなコードでMyErrorみたいな例外を定義します。なぜかと言うと、モデル層で発生しうるZeroDivisionErrorをアプリケーション層まで持ち越したくないから。とはいえ、元の例外を握りつぶすのもどうかと思うので、exceptionみたいなフィールドを作って、そこに格納することにしましょう。そこまで頭悪い感じの設計でもないと思います(とはいえ僕が一人で思ってるだけなので、わかりませんが)。

で、これを実行するとなんて出るかって言うのが今日の問題です。


んなもんrescue MyErrorに決まってるじゃん!と思うでしょ?思うでしょ??思うでしょ???


http://doc.ruby-lang.org/ja/1.9.3/class/Exception.html

Exception#exceptionは例外を発生させるメソッドで、raiseしたときにはこのメソッドが呼ばれ、得られた例外のオブジェクトが投げられます。なので、MyErrror#exceptionが元のZeroDivisionErrorになるので、rescueした結果を見るとZeroDivisionErrorなわけ。


テストが通ったようなので、そろそろデプロイします……

要望を、忘れることで穏便かつ確実にリジェクトする

先日ちょっと社内で議論をして、ユビレジの改善に関するアイディアの出し方を整理しました。これまでどうやってたかというと、BasecampのTodoリストにリストアップしていた。

これを止めることにしました。

基本的には、Discussionという機能を使います(要するにML)。共有はできますが、誰もそれについてフォローしない場合には勝手に時間が経つと消えていきます(消えないけど、誰も口にしない話は過去のものとなって忘れられていく)。これまでは古いものもToDoリストに残っていたわけですが、古いものは(誰かが議論を続けようとしない限り)忘れられていくようになります。

これまでは「放っておくとToDoリストに残り続けました」が、これからは「放っておくと過去の話になって忘れらていく」ということです。


はっきり言って改善のアイディアなんて放っておけばいくらだって出てくるわけです。少なくとも、経験的に常に開発につぎ込めるリソースではかばいきれないくらい多く出てきます。そううると、当然その中には「積極的にやってはいけない理由はないけど、ひとまずなかったことにする」ものが出てきます。というかかなり多い。この分別って、案外めんどうくさいものです。

きちんとした理由を説明することはできなくても、なんとなく野生のカンで筋が悪そうだと思うものがあったりします。こういうものは、ちゃんと説明してリジェクトするよりも、なんとなく消えていってくれる方がありがたくて安全なものです。うっかりリジェクトするべき理由を議論し始めると、うっかり論破され多場合に、不本意なものを実装することになります。実装するの自体は手間でないことも多いのですが、こういうものが後で問題になることは多いのです。

  1. そもそも無意識のうちに(野生のカンで)やるべきではないと思っているので、すぐに忘れてしまう
  2. 野生のカンというのは全体の設計とうまく整合性がとれていない場合が多いが、そうするとなにか特別な取り扱いが必要になってしまうことが多い
  3. 忘れてしまったものについては、後で別の変更をするときに特別な取り扱いが必要なことを忘れる
  4. ぎゃっと悲鳴を上げる事態が発生する

これは避けたいのです。ここでの過ちはなんでしょう?私はうっかり議論を始めてしまうことそのものだと思います。寝た子を起こさずに、そのまま永眠してもらうのが正しかった。


ところで、開発チーム、というか私が気づいていない問題があったときには、どういう風にそれを伝えれば良いのでしょうか?

まずはDiscussionに投稿することが一つの方法です。それが明らかに正しそうなアイディアならば、すぐに実装されるはずです。そうでない場合は忘れられていきます。ただし、本当に自分が重要だと考えていて、忘れられるわけにいかないと思っている場合は、しつこくDiscussionにコメントし続けて風化しないようにしましょう。それでもうまく行かなかったりスルーされ続けたような場合は、開発チームを誰か捕まえて、アイディアについての意見や改善するための方法を聞きます。その開発チームのメンバーから賛同を得られた場合には、そのまま実装してもらえば良いと思います。(あるいは自分で実装します。)

重要なアイディアは、多分なんども提出されるはずなので、忘れられたとしても問題はないはずです。バグのたぐいの問題はソフトウェア開発者のプライドにかけて可及的速やかに修正されるでしょう(今までと特に変わらないはず)。


一見、なんだかふわっとした方法でうまく行くのか良くわからない気もしますが、そもそも世の中はこういうもののような気もします。

オープンソースのプロジェクトの例だと、問題があったときにMLやバグ管理システムで報告するのも悪い手段ではないですが、ちょっと微妙な問題については自分で直してしまってパッチを送るというのが有効な手段なことが多いのではないでしょうか?MLで議論することもできますが、別の方法としては、どこかで開発者を捕まえて自分のアイディアを話して意見を聞くのが確実でしょう。

「どこかで」とか「開発者を捕まえて」というのがハードルになる場合はありますが、今回は社内での話が前提なので問題にはなりません。開発者は普通(建前としては)オフィスにいるはずですし、ユビレジくらいの規模の会社で相手の顔もわからないとか話したことがないとか確実にありえないわけです。

しばらくこんな感じでやってみようと思います。


なんかこういう、古いものは忘れていくことをencourageするようなタスク管理システムってないのですかね。ToDoの項目のなかで古いものはどんどん消えていくようなやつ。例えば締め切りとかは、すぎてからしばらくはアラートしてほしいけど、ある程度すぎるとだんだん消えていくのが正しいと思う。