From: whiteleaf <2nd.leaf@...> Date: 2015-01-21T21:57:37+09:00 Subject: [ruby-list:50069] Re: メソッドが無い「ふり」をする方法 やられたいこととは違うかもしれませんが。 module M refine String do def to_html "call #to_html" end end end def with_to_html yield end using M with_to_html do p "hoge".to_html end # => call #to_html require_relative "tt" # 他の場所でも with_to_html を使おうとすると undefined method `#to_html` refine 使えば using を使ったところでのみ String の拡張を制限出来ますね。 2015年1月21日 21:02 KISHIMOTO, Makoto : > きしもとです > > 内部(埋め込み)DSLなどで、Stringなど組込みクラスにモンキーパッチ的な > ことをしたいが、他の部分に影響を与えたくない、とします。 > > ブロックを使って yield の前後でメソッド定義を追加したり削除したりして、 > 以下のように書けると思うわけですが、目的のコンテキスト以外の場合を > スルーするために、カレントスレッドオブジェクトを使ってチェックする > ことにしました。 > # この方法についての議論もありそうですが、ここでの本題ではありません。 > > 本題ですが、こういった場合に、メソッドが無い「ふり」をする方法の > ベストプラクティスとしては、このように method_missing を呼ぶ、 > という方法で良いでしょうか。もっと良い方法があるでしょうか? と > いうのが質問です。 > > def with_to_yaml > cur_th = Thread.current > > String.__send__(:define_method, :to_yaml){ > unless Thread.current.equal? cur_th then > method_missing :to_yaml > end > > return self > } > > yield > > String.__send__(:remove_method, :to_yaml) > end > > with_to_yaml { > p "hoge".to_yaml > } > > # remove_method は ensure 節で実行するようにしたほうが > # 良いですね...