非同期処理を含む初期化処理を書くためにinitializeメソッドを生やすとよさそうなのでまとめる

背景

  • JavaScript のコンストラクタは async/await の書き方が使えない
  • 別メソッド呼べば?という解法は紹介されている

javascript

  • Async/Await Class Constructor - Stack Overflow</a>

自分なりのまとめ

基本

コンストラクタは使ってもよいが initialize を呼ぶ方が便利になるように作る。コンストラクタの中から別メソッドを呼ぶのではなく、初期化そのものを

await Klass.initialize(..)

で行えるようにする。基本はこんな感じ。

class Klass {
  constructor ({ arg1, arg2, .. }) {
    this.prop1 = arg1
    this.prop2 = args2
  }

  static async initialize (args) {
    ..
    const foo = await ExternalHeavyProcess(..)
    ..
    return new this(ARGS)
  }
}

ポイントは コンストラクタから見たときには DI になるようにすること。

こうすることで依存先を独立してテストしつつ、テストの際に依存ライブラリを差し替えたりパラメータを変更したりすることを容易にしておく。

全部開いて書くとこんな感じになる。

class Klass {
  constructor ({ arg1, arg2, .. }) {
    this.prop1 = arg1
    this.prop2 = args2
  }

  static async initialize ({
    arg1,
    arg2 = await ExternalHeavyProcess1(..),
    arg3 = await ExternalHeavyProcess2(..),
    ..
  }) {
    ..
    some processes
    ..
    return new this({ args1, arg2, foo, bar, .. })
  }
}

正直言うと長い。どうしても initialize の中が厚くなってしまう。とは言え、testability を確保しつつ async function を使いつつ class からオブジェクトを生成しようと思うと、おそらくこれくらいが現状はベストだと思う。

自身を返すか他者を返すか

初期化の処理が多くなりすぎたりオブジェクトの生成にしか直接関係しない(例えば Service Locator 周りの)コードが膨らんだりすると、実際のオブジェクトの役割が分かりにくくなってしまうので、そういう場合は

GRASP (object-oriented design) - Wikipedia

にしたがって creator に分離するとよいだろう。

一つのオブジェクトに対して二つの class が関係するのは高コストに見えるかもしれないが、根本的に高コストなオブジェクトを生成しているのだから仕方がない。高コストなことが可視化されただけ。

その場合は以下のような感じ。

class Klass {
  constructor (args)
}

class KlassCreator {
  static async create (..) {
    await method1ArroundCreation(..)
    await method2ArroundCreation(..)

    return new Klass(args)
  }

  static method1ArroundCreation (..) {
  }

  static method2ArroundCreation (..) {
  }
}

今度からrvmでruby入れるときはdocument忘れないであげたい

ri 使ってないよ chm で決まりでしょという人には無関係な、ものすごく今さらな話。

RVM: Ruby Version Manager - 'rvm docs' - Working with rdoc / yard.

手で作業するときは rvm1 で入れた 1.9.2 を常用してる2んだけど、実は「1.8 のときに超お世話になってた ri で全然ドキュメント見れなくてすげー不便」と思っていた。いろいろ調べて

yri + yard-doc-core gem

にしてたんだけど、実は

rvm docs generate するだけでよかった

ことが発覚。

なんてこった。これで ri の補完も活かせて嬉しい。

以下はこれを調べるきっかけになった Twitter timeline の抜粋。

19:27:23 <shinji_kono> ruby って、perldoc みたいな offline document な
いの?
19:27:47 <_ko1> @shinji_kono rdoc ってやつが(使ったことないですが)
19:30:46 <_ko1> @shinji_kono 私は windows 使ってるので chm ファイルで
見てます
19:39:17 <shinji_kono> 5分で学ぶRubyは書きました。が、Perl の方には
perldoc 使えって書けるんだけど、Ruby は rdoc ってわけにはいかないらし
い。
19:43:17 <nalsh> @shinji_kono 英語でよろしければ rdoc で、これはCソー
スないドキュメントが由来。「るりま」という日本語マニュアルプロジェクト
はそれとは別ってのが日本人にはちょっと複雑ですかね
19:56:08 <shinji_kono> どうも、Core なライブラリのドキュメントは ri で
引っ掛からないみたいだね。
20:01:18 <nalsh> @shinji_kono Ruby をインストールした時に rdoc を入れ
ていないのではないでしょうか
20:16:32 <shinji_kono> 僕の希望としては、ri File.open でなんか出て欲し
いです。
21:15:00 <wtnabe> @shinji_kono 自分もよく分からないんですが ri は 1.9
からあんまり役に立たなくて yri と yard-doc-core gem を使うとよさげな気
がします。この辺、コアな人たちの話題にあまりのぼらない印象。
21:24:11 <noplans> @wtnabe riで困ってないんですが、なんか問題ありまし
たか?
21:25:00 <wtnabe> @noplans うーんrvmで入れた1.9だとriで特にコアのドキュ
メント全然出ないんですよね。だから以前よりだいぶ不便を感じています。
21:27:09 <noplans> @wtnabe ri --list-doc-dirsにないとか、インストール
時にドキュメント入ってないとかですかねい
21:36:01 <wtnabe> rvmでの入れ方を間違ってるのかな
21:38:16 <wtnabe> 正しい方法が分かっていないということか
21:39:12 <wtnabe> http://beginrescueend.com/rubies/docs/ お。
21:40:20 <wtnabe> take a *long* time って言われた。bingo っぽい。
21:40:45 <wtnabe> まぁすでに yard-doc-core gem 使ってるんだけど。
22:14:29 <noplans> @wtnabe rvm でのインストール時に
--enable-install-doc つけるとドキュメント込みでインストールされないで
すかねい
22:23:47 <wtnabe> できてた。なるほど。

rvm install –enable-install-doc でもいいみたいだ。なるほど、いろいろ参考になりました。

※ ふと思ったけどここに出てるの、自分以外みんな大学の人?

Windows の場合

installer - ruby 1.9 ri problem - Stack Overflow

ちなみに Windows には ri 付かないっぽいけど、まぁ Windows なら chm でいいんじゃないすかね。自分は Mac だけど ichm - iChm is a CHM reader for Mac OS X - Google Project Hosting で便利に使ってます。これは複数タブ開けるので、以前ほど chm きらいじゃなくなりました。

myrurema という別解

yhara/myrurema - GitHub

るりまプロジェクトですね。コード内のコメントからの生成ではないのでラグがある代わりに日本語で読めます。

  1. まだ rvm なの? ぷぎゃーとか言わないの。 

  2. 待つのが面倒でまだ 1.9.3 にしてない。 

改めてRubyとbundlerとオープンクラスとgithubに感謝

Railsで初めてモンキーパッチを当てたときに変に感動して連投したtweetより。

11/01/20 10:43 Railsの中身がよく分かってないのでどこで対処すべきかうま
               く判断できない。でも Ruby だからなんとかなるだろうと読
               んで踏み出したし、実際なんとかなった。オープンクラス最
               高。
11/01/20 10:44 Ruby + githubの組み合わせがとてもよい。モンキーパッチで
               対処できるし、最悪本家へのフィードバックが届かなくても
               github的な意味でforkしてしまえばよい。
11/01/20 10:48 加えてbundlerがステキ。bundlerでforkしたrepository見に
               いくようにすればアプリ側は何も気にする必要がない。
11/01/20 10:49 PHP + svnのライブラリでパッチ投げて無視された(内容云々
               じゃなくてもうメンテ継続してない)ことが何回かあるけど、
               この場合面倒くさい。モンキーパッチも作りにくいし、fork
               も面倒。bundlerのような仕組みもないのでライブラリをこっ
               そり差し替えたりするのが手間。
11/01/20 10:57 Railsもまぁいろいろあるんだろうけど、自分はやっぱRubyの
               方がしっくりくるな。http://bit.ly/hxmmTb 「Lisperは臆病
               なんです。」とても強く響いている。実は。

いっぱい書こうと思えば書ける話なんだけど、膨らみすぎるのでそのままにしておく。

Lisp:よくある正解

Ruby は Lisp だなんてことを言うつもりはないし、そんなことが言えるほど Ruby も Lisp も分かっているとは思っていない。でもこの言葉は自分の中でとてもしっくりきている。

そういう状況において、「どんなに汚くても、打てる手段がある」というのは 何物にも替え難い救いなのです。というより、そういう予想外の事態に対して エスケープポッドが備えられていない処理系を使うなんて恐くて出来ません。 Lisperは臆病なんです。

例えばオープンクラスでない言語 + github などの fork 上等なリポジトリホスティングを使っていないライブラリやフレームワーク1を採用してしまった場合、後から「しまった」と思ってもどうにもならない。

ある程度 Ruby を使える自信があるなら、それは下手な「実績」なんかより Ruby を採用する理由として十分だ。今なら以前より強くこれを言える。

LL だから、OSS だから、だけじゃないんだよな。

  1. PHP + sf.net とか 

rqr を使って Ruby で QRCode 画像を作る

[2014-05-02 追記] ここで書いている rqr は基本的に Ruby 1.8 用でした。その後アップデートされている可能性はゼロではありませんが、1.9 でも動くように自分で

wtnabe/rqrcode_png_bin

を書いてそちらを使っています。興味ある方はどうぞ。


さぁ、今さら日記シリーズが復活しましたよ。

QRCode 画像を Ruby で作る

QRコードを算出する部分は ext だし、画像を吐き出す部分はネイティブのライブラリに依存しているので、多少準備が面倒だけどたぶんそれなりの速度が期待できる。

実は以前から one-liner なんかで使ってはいたんだけど、改めて定型作業に使えるようにちょっとしたスクリプトを書いてみた。

で、そのときに気づいたんだけど、これ、サイトのサンプルコードが間違っている。

RQR::QRCode.new
RQR::QRCode.create

が同じように動くように書いてあるんだけど、new の方は block は受け取らない。create の方は block を受け取って close するまで全部まかなってくれる。あと、Windows 版で面白くない動きをする。

2009-10-14 の twitter のログより。

14:34:29 >wtnabe< あー rqr 0.2.2 は Windows でバグってるのか
14:48:53 >wtnabe< 分かってきた。RQR::QRCode.new.save だと怒られる。
RQR::QRCode.new { |qr| qr.save } だと大丈夫。でも close がないって怒ら
れるのはちょっと不安だなぁ。

ということで create 使っておくのがいちばん無難なのかな。Windows でなんか文句言われるのは今のところ握りつぶしておくしかないみたい。

※ なんか、咳さんが非gem環境でインストールしてる。

画像が必要ない場合は他の方法でもいいけど

実はもう Web 上に QR コードを表示させるためだけならこういう画像を生成するツールはなくてもよかったりする。なぜなら JavaScript があれば動的に生成できるから。

でも例えば印刷用に画像を用意したいとかいう場合はやはり「画像」を自動生成する方が楽。実際にはこの rqr だけでは細かい調整をするのは大変なので、ImageMagick などを噛ませる必要があると思うけど1

  1. 実際、件の ImageMagick のオプションを調べたのはこのため。 

カレントディレクトリの php.ini は勝手に読み込まれる

PHP、またか。

php-cli は -c オプションで ini ファイルを指定することができる。

$ php -h
Usage: php [options] [-f] <file> [--] [args...]
       php [options] -r <code> [--] [args...]
       php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]
       php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]
       php [options] -- [args...]
       php [options] -a

  -a               Run interactively
  -c <path>|<file> Look for php.ini file in this directory
  -n               No php.ini file will be used
...

まぁこれは知ってたんだけど、今日ビックリしたのは

-c で指定しなくてもカレントディレクトリの php.ini ファイルは勝手に読み込まれてしまう

こと。

最近、PHP のテストをよく cli でやっている1んだけど、その関係で環境やサイトごとにまず ini ファイルを生成して、それを -c で読み込むようにしていた。Web ベースで言えば .htaccess を用意して切り替えるようなイメージ。

しかし、どうも意図しない設定変更がどこかで起きているケースが頻発して訳が分からなくなってしまった。

よくよく追いかけると -c で指定していないカレントディレクトリの php.ini ファイルの内容が反映されていた。これは試しに置いていただけで全然使うつもりがなく、

php -c ../../php.ini -f testfile.php

みたいに実行していたんだけど、カレントディレクトリのもので上書きされてどう逆立ちしてもテストが通らない状態になっていた。

仕方ないので生成する ini ファイルは

php.my.ini

という名前に変更した。なんだかなぁ。

  1. HTTP でパラメータを与えなくてもその部分がちゃんと抽象化されていればユニットテストは十分できる。このやり方の方が余計な仕事をやっている Apache や拡張だらけで重たくなったブラウザを使わずにテストできて速い。速さは正義だ。 

netselect であれこれ

※ netselect のオリジナルってどこなんだろ。各パッケージシステム(apt, gentoo, ports など)から手に入るんでいいんだけど。あ、Fink にはないな。

普段はこれと言って気にしてないんだけど、FreeBSD mirror はどこが近いのかなーと思い、自分で ping を打ちまくるツールでも書こうかと思ったけど、それもなんか面倒だと言ったら netselect を教えてもらった。

netselect HOST HOST HOST HOST

と書いていくと、いちばん反応の速いホスト名が返ってくるんだけど、例えば zsh 上では

netselect -vv 192.168.0.{1..254}

とやるとローカルのネットワーク上の IP アドレスの生死のチェックもできる。

netselect `cat FILE`

とやれば、あらかじめホスト名を列挙しておいたテキストファイルからリストを展開してチェックできる。いろんな目的に合わせて mirror サイトのリストを切り替えて使うことができるわけだ。便利便利。

ただし、ping によるチェックらしいんで ping を叩き落としているサイトのチェックには使えないと思う。

と思ったら純粋な ping ではないっぽい。ip alias の分は死んでいると返ってくる。実際に ping を打つと alias と言えど生きているのでこの返事はちょっと困る。何か詳しいこと知ってる人は教えてください。

mtr

OSX + Panther + Fink の組み合わせには netselect がないんでどうしようかと思っていたら

MTR

を見つけた。これは ping と traceroute を組み合わせた動きをして細かい様子を観察できるもの。gtk と curses で動く様子のスクリーンショットがリンク先から見れるので雰囲気はだいたいつかめると思う。これを

mtr -r -c 10 HOST

てな感じで report mode で動かしてやると curses でも gtk でもなく標準出力に出せるので、for と組み合わせたりして適当に加工すれば目的のデータの収集はできそう。

Frenzy 1.1 は SLAX のようなカスタマイズが可能に?

Project Frenzy - FreeBSD-based LiveCD

※ なんで news に permlink ないんだー。

SLAX って Slackware ベースの LiveCD か。Live CD Linux としては日本では産総研の影響で knoppix だけ突出して有名だけど、どーも好きになれないんだよな。Slackware にもそれほどいいイメージはないけれど(^^;、knoppix よりはなんか相性よさそうな気がする。

FreeBSD 6.2R も出たし、Frenzy 1.1 に期待してみよう。

cf.

ついでに DSL(Damn Small Linux) とかメモ

knoppix をうざいと思っているなら代わりのものを探せばよい。つーことで

この辺からちょっと試してみようか。

クーラーをファンレスにしたが効果なかった

つーことは HDD からくる振動か。こっから先は茨の道だなぁ。もっと高いケースにすべきだった? いやーキツいよ。きついですそれは。

ここで踏みとどまらないと完全に静音スパイラルだ。やめておこう。

[追記]ふすまを挟んだら効果が分かった。ちょっと音が減ってるらしい。ビミョー。このために5000円使ったのかぁ…。まぁいいか。こんなの自己満足だからな。

NTサービスのアンインストール

http://home.monyo.com/technical/windows/31.html

ありますねぇ、こういうの。

About

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