たぶんそうとうアホなこと書いてると思うんだけど、例えばファイルを読むとき例外が出たらSTDERR.putsとかでエラーを書いたりするみたいなんだけど、普通はコンソールに出力されるだけでそれを呼んだメソッドとかはどうやって読むつもりでいるのかという疑問が起きた。
業務アプリとか書いてるとメソッドとかでエラーが出る場合は戻り値はboolでクラスにエラーメッセージを格納するメンバとか作ってそれを読むみたいなのがありがちだと思うんだけど、rubyに限らずjavascriptとかperlとかのgithubにあるいろんなsource読むと例外処理を入れてない漢らしいメソッドがけっこうあって、例外が起きたときはなるがままに落として呼んだほうで例外を拾って対処するのが一般的なのかもしれない。
こういうのは仕様とか実装の問題だと思うんだけど、どこまでクラスが責任を持つべきなのかというのがわけわからなくなってきてる。
それはともかく、いくら例外をrescueで拾ってSTDERRに書いたところでそれを読めないのならなにが理由でダメだったのか知る手段がないんじゃないかと思ったので読んでみたい。
リファレンス読むとSTDERRは$stderrのデフォルト値で要はIOクラスっぽい。
これ読むとそのものズバリでSTDERRの出力先を変えることができて、それを読めばいいということになる。
reopenの引数はIOなのでファイルでもいいんだけど、IOのリファレンスをずーっと読んでいくとpipeってやつがreadとwriteのIOを返してくれるっぽい。
これは相互につながってるらしいので、片方で書いたら片方で読めるということになる(と思う)
試してみる。
STDERR.puts "start" stderr = STDERR.dup r, w = IO.pipe STDERR.reopen w STDERR.puts "puts" p r.readline STDERR = stderr $ruby std.rb start "puts\n"
ちゃんと読める。すごい。
念のため、readlineをコメントにしてみる。
STDERR.puts "start" stderr = STDERR.dup r, w = IO.pipe STDERR.reopen w STDERR.puts "puts" #p r.readline STDERR = stderr $ruby std.rb start
出ない。すごい。
ということは、STDINにpipeのreadをセットすればSTDIN.readlineで読めるのではないか。
やってみる。
STDERR.puts "start" stderr = STDERR.dup stdin = STDIN.dup r, w = IO.pipe STDERR.reopen w STDIN.reopen r STDERR.puts "puts" p STDIN.readline STDERR.reopen stderr STDIN.reopen stdin $ruby std.rb start "puts\n"
読める。すごい。
というかここまでやって思ったけど、なにもせずSTDERRとかSTDOUTに出力したら拾えないってことだとしたらいまやったことは目的を果たしていないというか無駄なことだったっていうか...
いろいろぐぐってるけどそれらしいものはまだみつかってないので、できるのかできないのかすらまだわかってない。
よくわからない。