すがブロ

sugamasaoのhatenablogだよ

花粉症がマジヤバかったけど空気洗浄機を買ってからマジヤバくなった話

花粉症マジヤバい

わたくし、花粉症はかなりのベテラン選手でして、かれこれ17年くらい花粉症なんですね。いま気がついたけれど人生の半分以上花粉症ですね!!
どのくらいヤバいかというと

  • クシャミが一度出ると少なくても5〜6回は出るし、へたしたら10回くらいクシャミしてる気がする
  • 朝、目を覚ますとまぶたが目ヤニでくっついてあけられない
  • 目の充血やかゆみもホントひどくて、がまんできずに目をゴシゴシしてしまう

っていう感じ。ここ10年くらいは概ねこんな感じで花粉の時期を過ごしていました。
目薬や飲み薬は基本的に手放せない状況ですね。飲み薬を飲んでいてもクシャミも少しは出るし、朝とかは特に症状がツライ。

空気洗浄機マジヤバい

2月末に空気洗浄機買ってみたんですよ。そうしたらマジヤバくなった。

  • クシャミはたまーに(数日に一度くらい)出るくらい。ほとんど連続にならないし、電車に乗った瞬間ムズムズくるような感じでもない
  • 少し涙目になっていたり、目ヤニが出たりするけれど、目が開けられないレベルと比べると雲泥の差(目尻にちょっとついてる程度)
  • 目のかゆみもある程度軽減されていて、以前ほど目薬のお世話にならなくなった(去年とかは一日に何回も指していたけれど、いまは一日に一回指すかどうか)

効果があるのは主に帰宅直後や寝起きの時の症状なのだけれど、帰宅〜出社の間に花粉まみれになっていないからか、日中の症状もグッと軽くなっていて、花粉症でキツイわ〜とか言っていても昨年にくらべれば全然大したことないレベルでマジヤバい。

もしかしたら今年の花粉が異常に少なかったのかもしれないけれど、毎年このような症状なので、おそらく空気洗浄機のおかげだと思われる。

加湿機能マジヤバい

買った空気洗浄機は加湿機能もついてるんですよ。これもマジヤバい。
たまに、エアコンつけたまま寝ちゃう事あるじゃないですか。口パカッて開けたまま寝てたりすると、起きた時のカピカピ感ヒドイですよね。じゃっかん枯れそうですよね。そのような乾燥っぷりも加湿機能のお陰でだいぶ改善しました。これはおまけみたいなものだけれど、まさにお買い得。

空気洗浄機マジヤバい

持ってない人は買ったほうが良いですよ。本当に買ってライフチェンジングしました。
空気洗浄機の良し悪しがわからなかったので、とりあえず一番安いヤツを買った*1のですが、元々の値段が6万なのでそれなりにパワーのあるヤツだったのかもしれません。オススメです。

ダイキン(DAIKIN) 加湿空気清浄機「うるおい光クリエール」 バニラホワイト ACK55M-W

ダイキン(DAIKIN) 加湿空気清浄機「うるおい光クリエール」 バニラホワイト ACK55M-W

*1:1万8千円くらい

curlで HEAD レスポンスを見るメモ

いつも忘れるので

-I で見れる。そんで-Lも付けておくと、リダイレクトを追跡してくれるので、どんな風に動いているかわかりやすいですね。

% curl -LI http://yahoo.co.jp/
HTTP/1.1 301 Moved Permanently
Date: Mon, 26 Mar 2012 09:37:04 GMT
Location: http://www.yahoo.co.jp/
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=utf-8
Cache-Control: private

HTTP/1.1 200 OK
Date: Mon, 26 Mar 2012 09:37:04 GMT
P3P: policyref="http://privacy.yahoo.co.jp/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"
Expires: -1
Pragma: no-cache
Cache-Control: private, no-cache, no-store, must-revalidate
X-XRDS-Location: http://open.login.yahoo.co.jp/openid20/www.yahoo.co.jp/xrds
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=utf-8

例外戦略

まぁ正しく例外を使いましょうという話ですね。当たり前でしょと思う人は読まなくて良いです!!

前口上

例外に限らず、自分がプログラミングをするにあたって心掛けていることの一つに、誠実なプログラミングというのがある。最近、思いついたので勝手に名前をつけてみたんだけど。
何かっつーと、何が起こっているか、であるとか、これから使うデータはこれです、と言ったものをきちんと伝える・伝わるようにしておく、という心構えです*1

その中でもとにかく例外はきちんと扱って欲しい事の一つなので、ちょっと自分はこーしているというのを世に残しておくのも良いかなぁと思った次第です。

例外はたくさんの重要なデータを持っている

概ねここらへんの情報は例外機構を持ってる言語なら提供してくれると思います。

Ruby だったら class Exception を見ればどのようなデータが取れるかわかりますね。
コードを見たほうが早いかな。

require 'fileutils'

class Hoge
  def fuga
    FileUtils.rm('/tmp/hoge/fuga')
  end
end

begin
  Hoge.new.fuga
rescue => e
  puts "e.class     => #{e.class}"
  puts "e.message   => #{e.message}"
  puts "e.backtrace => #{e.backtrace}"
end
sugamasao@GRAM% ruby hoge.rb 
e.class     => Errno::ENOENT
e.message   => No such file or directory - /tmp/hoge/fuga
e.backtrace => ["/Users/sugamasao/.rvm/rubies/ruby-1.9.3-head/lib/ruby/1.9.1/fileutils.rb:1406:in `unlink'", "/Users/sugamasao/.rvm/rubies/ruby-1.9.3-head/lib/ruby/1.9.1/fileutils.rb:1406:in `block in remove_file'", "/Users/sugamasao/.rvm/rubies/ruby-1.9.3-head/lib/ruby/1.9.1/fileutils.rb:1411:in `platform_support'", "/Users/sugamasao/.rvm/rubies/ruby-1.9.3-head/lib/ruby/1.9.1/fileutils.rb:1405:in `remove_file'", "/Users/sugamasao/.rvm/rubies/ruby-1.9.3-head/lib/ruby/1.9.1/fileutils.rb:785:in `remove_file'", "/Users/sugamasao/.rvm/rubies/ruby-1.9.3-head/lib/ruby/1.9.1/fileutils.rb:563:in `block in rm'", "/Users/sugamasao/.rvm/rubies/ruby-1.9.3-head/lib/ruby/1.9.1/fileutils.rb:562:in `each'", "/Users/sugamasao/.rvm/rubies/ruby-1.9.3-head/lib/ruby/1.9.1/fileutils.rb:562:in `rm'", "hoge.rb:5:in `fuga'", "hoge.rb:10:in `<main>'"]

この例だとメッセージだけでおおよそ見当はつくけれど、存在しないファイルを消そうとしたという例外が発生したってわかりますよね。で、スタックトレース*3を見ると、hoge.rbの5行目で定義されているfugaメソッド内で呼んだfileutilsのrmが呼ばれてるなーとかわかるわけ。そうすっと、今回は一個だけだからすぐに特定できたけれど、複数の処理のどこで例外が起きたとかもわかるよね。

昔はActionScript3*4を書いてる時期があって、ASで書いたらどんな感じになるんだっけ、と思ってちょっとAIRで書いてみたよ*5

ASの場合、いわゆる例外と、例外イベントの二種類があるのが厄介ですね。

			import flash.filesystem.File;
			import flash.filesystem.FileMode;
			import flash.filesystem.FileStream;

			import mx.controls.Alert;

			protected function button1_clickHandler(event:MouseEvent):void {
				try {
					readData();
				} catch (error:IOError) {
					Alert.show("errorID = " + error.errorID.toString());
					Alert.show("message = " + error.message);
					Alert.show("name = " + error.name);
					Alert.show("stacktrace = " + error.getStackTrace());
					Alert.show("errorClass = " + flash.utils.getQualifiedClassName(error));
					trace("errorID    = ", error.errorID);
					trace("message    = ", error.message);
					trace("name       = ", error.name);
					trace("stacktrace = ", error.getStackTrace());
					trace("errorClass = ", flash.utils.getQualifiedClassName(error));
				}
			}

			private function readData():void {
				var file:File=File.desktopDirectory.resolvePath("sample.txt");
				var stream:FileStream=new FileStream();
				try {
					stream.open(file, FileMode.READ);
				} finally {
					stream.close();
				}
			}

			protected function button2_clickHandler(event:MouseEvent):void {
				var loader:URLLoader=new URLLoader();
				loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
				var request:URLRequest=new URLRequest("MissingFile.xml");
				loader.load(request);
			}

			private function ioErrorHandler(event:IOErrorEvent):void {
				var e:Error=new Error();
				trace(event.text);
				trace(event.type);
				trace(e.getStackTrace());
				Alert.show(event.text);
				Alert.show(event.type);
				Alert.show(e.getStackTrace());
			}

当然、デバッグモードの時しかtraceでない(Flex4からはそうなったのだ!!)けど、リリースモードだってきちんと文字列は取れるので活用しない手は無いよね*6

# ここは普通の例外
errorID    =  3003
message    =  Error #3003: File or directory does not exist.
name       =  Error
stacktrace =  Error: Error #3003: File or directory does not exist.
	at flash.filesystem::FileStream/open()
	at Hoge/readData()[/Users/sugamasao/Documents/Adobe Flash Builder 4/Hoge/src/Hoge.mxml:39]
	at Hoge/button1_clickHandler()[/Users/sugamasao/Documents/Adobe Flash Builder 4/Hoge/src/Hoge.mxml:20]
	at Hoge/___Hoge_Button1_click()[/Users/sugamasao/Documents/Adobe Flash Builder 4/Hoge/src/Hoge.mxml:62]
# ここからイベントハンドラ
errorClass =  flash.errors::IOError
Error #2032: Stream Error. URL: app:/MissingFile.xml
Error
	at Hoge/ioErrorHandler()[/Users/sugamasao/Documents/Adobe Flash Builder 4/Hoge/src/Hoge.mxml:53]
	at flash.events::EventDispatcher/dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at flash.net::URLLoader/onComplete()

薄い記憶通り、後者のイベントハンドラだとろくなメッセージが帰ってこないw だもんでイベントハンドラで受け取った時にスタックトレース出したら結構良いのでは、と思ったけどイベントが発火したことのスタックトレースがでちゃってあんまり役に立たないね。
とはいえ、最低限どのようなエラーが返ってきているかはわかるし、たぶん作りによってはcurrentTargetとかからもっと良い情報が取れる気もする(もう全て忘れたのでテキトウ)。

閑話休題

さて、これらの例外が起こった情報というのは当たり前だけれど、アプリケーションがどのような状況に陥ったかを調べることができる重要な情報だ。とりあえず動けば良いやーというものであればテキトウな対応をして、あとでチマチマ調べるということもできるかもしれないけれど、なにか起こった時に「いやーよくわかりませんねーw」とか言う状況っていうのはプロとしては腹を切って死ぬべき状況だと思う。

……時には対応が漏れたりするときもあると思うけれど、それは発覚した時にきちんと再発しないように対応するのがプロです。

例えば、こんな(笑い話でよく見る)コードを書いていたら腹を切って死ぬ覚悟をしたほうが良い*7

begin
  なんとかの処理
rescue => e
  # 何もしない
end

コレ以外にもこのような例も腹を切って死ぬ覚悟が必要になるケース。

begin
  なんとかの処理
rescue => e
  raise 独自例外クラス.new
end

例えば、イベントドリブンなものではこんな感じか

private function errorEventHandler(e:Error):void {
  this.dispatchEvent(new 独自イベント(独自イベント.ERROR));
}

あまりに例外が明示的すぎてこれで十分な可能性もあるけれど、既に起こった例外の情報を全て捨てて、新たなイベントや例外を起こすというのはほぼ例外の握りつぶしに等しい。気を効かせたつもりかもしないけれど、大きなおせっかいにしかなっていない例である。やるなら、元の情報をもたせた上での例外送出を行うべきである*8

おれ自身はRubyで書くことが多いので、こんなふうにしてコンストラクタで渡したりする。例外クラスの情報をシリアライズ化させるメソッドを定義して、そこを通すようにしているっていうのが正解かなぁ。フォーマットとかはテキトウなんだけど、少なくとも値が空だった時に空だったってわかるように、値の部分に何かの囲いを付けるようにしている。

begin
  なんとかの処理
rescue => e
  raise 独自例外クラス.new("なんとかしようとしたら例外が出たよ >Class=[#{e.class}], message=[#{e.message}], stacktrace=[#{e.backtrace}]")
end

エラーイベントでもmessageとか、取れるものはきちんと取ってイベントをディスパッチしてあげれば良いよね。

どのようにアウトプットすべきか

エラーが起こった情報を取得することができたとして、ではどうやってアウトプットすれば良いか。

サーバサイドアプリケーション

いわゆるサーバサイドではすごく王道の選択肢があるので、それを使うのが良いですよね(さすがにこれが無いのはヤバい!!)。

  • 自前のログファイルに出力する
  • syslogやEventLogみたいなOSが提供するログシステムに出力する
デスクトップアプリケーション

デスクトップアプリケーションの場合は結構難しい。結局、ユーザから送ってもらうなりしないといけないケースが多いし、ファイルに落とすにしても自力管理するハメになる可能性があるからだ。

  • 自前のログファイルに出力する(自前でログファイルの管理が必要かも)
  • syslogやEventLogみたいなOSが提供するログシステムに出力する
  • レポート送信機能的なもの(アプリケーションやOSが落ちた後に出てくるアレ)
  • 独自に定義したエラー番号とかをアプリケーションが終了するときにアラートとかで出しておく

ココらへんはアプリケーションの性質やUIとの兼ね合いもあるけれど、レポート機能みたいのが一番無難なんですかね。
補足:私はデスクトップアプリケーションを開発した経験がないので、こーいうやり方が良いよ!という方法があれば教えて下しあ

この場合とはちょっと話が異なるけれど、JSの場合はonerror関数を使って例外をキャッチして例外が発生した用のURLに情報を投げる、なんてのを聞いたことがありますね。

本当はログの出力方針についての話も書こうと思ったけどなんか既に話が長くなったので辞めた。
よーするに要点を押さえて出す(ファイルI/Oはとても遅いのでたくさん出すのはデバッグ版だけにするんだよ)とか、ログレベルとかビルドオプションとかできちんと切り替える機構を使おうとかそういう話なので、まぁ普通の開発者は知ってることですよね……。

あわせて読みたい

プログラマが知るべき97のことには、カテゴリ別の目次もあるんです。そのカテゴリとして"エラー、例外とその処理"という項目があるので、読んでみると良いでしょう。

え、まだ本を持ってないですって?ここのリンクから買うと良いんじゃないですかね!!

プログラマが知るべき97のこと

プログラマが知るべき97のこと

*1:心構えっつーか、そういうのをコードに落としておくということ

*2:例外が発生したクラス自身も結構重要な手がかりになるのだよ

*3:この場合backtraceだけど

*4:というかFlex3

*5:AS3忘れすぎて、いわゆるtry〜catchのエラーが出る処理をぱっと思いつかなかったので……

*6:という確認のためにAlert出した

*7:物によっては例外が出たらリトライ処理をするとかあるから、一概に例外を握りつぶすのがダメとは言えないが

*8:ライブラリではまた違う設計になると思うけど、ここはあくまでもアプリケーションレベルの話ね

掲載された部屋について一言言っておくか

Web男子記事に掲載されました

オマエは何を言っているんだ?という方はとりあえずこっちを見てくださいね。

……読んだかな。
それじゃあ、あの部屋ができるまでの過程を少し書いていくよ。

引越しについて(引越し前の回想シーン)

引越しする前は圧倒的な汚部屋でして、机の上に物が重なってホコリが積もってるとかざらでした。
で、なんとかその汚い空間から逃げ出したかったので引っ越したんですね。

引越しにあたり、せっかく買った物などでも使う機会の無いものはものすごい勢いですてました。
CDやゲーム、本等は大部分を売りました。CDとかはiTunesで取り込んであれば二度とCDから聞くことは無いし、そこまで音質にこだわりも無い。本も技術書の類では古いものはオワコン化しているものや、現状 Perl やら Java やらは触らない*1と思い、ガッツリ処分した。

処分について

CDやゲーム等はブックオフの買取サービスを頼んだ。

ダンボールに詰めておけば無料で集荷がやってきて、仮に値段がつかなくてもそのまま引きとってくれるので、とりあえず全部いらないのはぶっ込む*2
技術書関係はここに頼んだ。ブックオフよりはまともな値付けをしてくれたと思うし、集荷の調整とかを丁寧にやってくれてとても印象が良かったです。
ブックオフと同じで、値段がつかないものはそのまま処分してくれるので、ダメもとの気持ちがある本等も遠慮無くダンボールにつめた。

ちなみに、ファーストコンタクトは Twitter( @bookcyber )上で、その場で疑問に思ったことは丁寧に回答してくれたのも決め手。
他にはベッドや机などもあったのだけど、それは引越し業者に処分を頼んだ。各種1〜3000円程度で処分してもらえるので、自力で粗大ごみに出すのと大して変わらなかったりするので。

部屋作り

今回、新しく部屋を設計するにあたり何を意識したか、というと

  • 家具等を低めにして圧迫感を出さない*3
  • 物を置かない(きちんと置く場所を決めておく)

という点。まぁ、よく言われる点ですよね。

基本的には以下のお店で家具を揃えた。さぁ、以下のアフィリエイトから購入しましょう*4!!

あと、PCを使うときのイスは Leap(リープ)チェア を中古で買った(イスの中古っていうのは結構流通しているので探してみると良いよ*5)。

物を置かないということ
  • レターケースを買って、請求書の類等は集めておく
  • サイフとキーケースが丁度入る小物入れを見つけて、机の上に "とりあえず" と置かないようにする

以前までは置き場所がなくて

  1. とりあえず机の上に置いておこう
  2. 積み重なって掃除できない
  3. 掃除する気力がポポポーン(・∀・)

となっていたので、極力ごちゃっとなりえそうなものは置くエリアをつくろうと意識した結果、"ちょっとどける"がしやすい構造になって、掃除もやりやすくなった。

オチとかないんですけど

偶然にもこれから引越しを検討している方のご参考になればと思います。
ちなみにこのボールペンは本当にかき心地が良いので、興味があればぜひ、使ってみてください。

*1:触るときにモダンな本を買ったほうが良い

*2:値段がつかなくても処分してくれると思えば良いやという精神で

*3:現在、部屋の中で一番高いのは今まさに使ってるPCのモニターです

*4:僕が幸せになれます

*5:不謹慎な話、倒産している会社があるということは中古に出回る可能性も……

RealForce のキーボードが欲しくて欲しくて仕方がない

買うと決めた

会社で使うキーボードってたぶん、年間でも最も触る機会があるデバイスな気がするのできちんとしたものを使いたい。
しかも、今使ってるキーボードはEscキーの利きが悪いので、 gVim 使った時に発狂するという事情もある。

で、買うなら

  1. 日本語配列キーボード
  2. テンキー付き

という条件がいいなぁと思ってたのだけど、その条件だと選択肢はほぼ無いに等しいw
というかこれしかない。

本当は HHK の打鍵感もすごく好きなんだけど、テンキーがついてないと常用としてはちょっと面倒だし、テンキーを別にするっていうのもダサい。
なので、RealForce にしようと思った次第。
で、カカクコムで買おうかと思ったけど、できれば早く欲しい。ドヤ顔で出社したい。というわけで新宿で実物を触りながら買ってこようと思った。思ったんだが、どこに行っても品切れという\(^o^)/

捨てる神、拾う神

で、しょんぼりしながら帰る途中、Twitterでこんなキャンペーンをやっている事を知る。

来週まで持ち越しか!?><【目指せフォロワー1,000人企画】1,000人到達時に、当社オリジナルキーボード“Realforce”(http://bit.ly/9xEWwu)を抽選で@ilovex_officialフォロワーにプレゼントします。

@ilovex_official をフォローするだけで夕張メロンカラーの RealForce が当たるらしい。すごい!!!
というわけで早速フォローしたし、1000人集まらないと抽選しないっぽい?のでみなさんとりあえずフォローしておくと良いんじゃないかな!*1

*1:キーボード要らない人はおれにくれ!!!!

2009年の振り返りと2010年に向けて

本当は

2009年のうちにこのエントリを上げたかったのですが、年末までバタバタしてしまってこんな時期です><

2009年の主な出来事

1月
  • 仕事が暇すぎて Ruby on Rails でちょっと資産管理っぽいアプリを作ったり、Hudson の布教用資料を作ったり
  • 現職の面接を初めて行った
2月
  • Developers Summit に参加して、サインを貰ったりしつつ、スタンプラリーでVS2008のパッケージがあたった
  • 仕事では以前携わったシステムの運用・保守チームに休職者が出たので、人員を確保する間の繋ぎとして、保守とかをやるハメになった
  • perl の運用ツールの改修とか、Javaの運用ツールの改修とか、そーいうのをやってた。誰よりも遅く出社して誰よりも早く退社するという舐めきった勤務態度でしたね*1
  • 現職での最終面接まで行ったのもこの月
3月
  • 仕事が死ぬほど退屈で死ぬかと思った月だった気がする
  • 暇すぎて、C言語のSIGNALの使い方を調べるくらい暇だった。 SIGNAL を受信する - @sugamasao.blog.title # => ”コードで世界を変えたい”
  • 暇すぎていろんな人を誘って飲みに行きまくってひと月に15回飲みに行って、5回くらいはタクシーで帰るような生活を送っていた。ひどい。
  • あと髪を短くしたのもこれくらいの時期だった気がするなー*2
4月
  • 内定もらった
  • 退職を会社に伝えた
  • いろいろ上司と話てよく考えろと言われた
5月
8月
  • 6〜7月でいろいろ飛ばした反動か、燃え尽きていた気がする
  • Flex でのコーディングが本格化してきて、ソースの構成などが気になってきたのがこの頃
10月

人生初の、ちゃんとした場での発表(LTだけどw)だったのですが、ありえないほどの緊張で時計なんか全く見ることができず、ひどいプレゼンになってしまいました。次の機会ではもっとkeynoteを使いこなしてカッコよくプレゼンしたいです><

11月
12月

これを元に KPT で分析してみます。

それにしても、振り返ってみると6月7月の活発っぷりが異常で、それ以外は案外大した事はしてなかったなーと思う。
その他での大きいところは楽天での発表くらいですからね。。。

Keep
  • ライブラリやWebサービスの作成は今までに無いくらいまともなモノを作ることができたので、この調子をキープしていきたい
  • 何らかのイベントでのLTなどの発表
  • 新しいテクノロジーに触れてみること(去年で言う GAE や Air みたいな感じで)
  • ブクマをそこそこ集められるようなエントリがかけた
Problem
  • アウトプットに対する波が激しすぎて、ダメな時は何もやる気がでなかった
  • リリースしたはいいものの、きちんとメンテできていない
  • LT がヘタレw
Try

総括すると

基本的には現状ベースでもっと質を上げていく方向で活動していきたいってことですね。
みなさん、本年もよろしくお願いいたします!

*1:通常はエラーとかが無ければやる事なんてたかが知れてただけですが

*2:年末に久しぶりに会う人に、髪が短くなってって一瞬わからん!って言われたので一応書いておくw

*3:Air1.5でビルドしなおします

*4:紙面でもWebでも媒体は何でもイイんですけど