なかだです。

On 2016/10/25 14:04, yamataka / u08.itscom.net wrote:
> インスタンスメッソド hookについて、質問させて下さい。
> 
> 下記のclassのインスタンスメッソド内で、
> if !@is_in_nw then … return nil end を実行している method が多数でてきた
> ので、
> 該当部分を、hook を用いて記述すれば、綺麗なコードになるなと思い、Web等で
> 色々調べたのですが、
> これといった方法が見当たらず、良い記述方法があれば、ご教示いただけますで
> しょうか?

2.1以降用ですがこういうのはどうでしょうか。

```
class WebAPI

  attr_reader :is_in_nw

  module InNetwork
    def _check_in_nw
      unless @is_in_nw then
        warn "TV(#{@ip}) is not in Network"
        return nil
      end
      true
    end

    def self.check(name)
      define_method(name) do |*args, &block|
        super(*args, &block) if _check_in_nw
      end
      name
    end
  end
  prepend InNetwork

  def initialize(ip,is_in_nw=false)
    @ip = ip
    @is_in_nw = is_in_nw
  end

  InNetwork.check def getInformation
    :info
  end

  InNetwork.check def Register(code)
    :Register
  end

  InNetwork.check def Play(function)
    [:Play, function]
  end
end

tv_obj = WebAPI.new('offline')
p tv_obj.Play("tuner") # nil
tv_obj = WebAPI.new('online', true)
p tv_obj.Play("tuner") # [:Play, "tuner"]
```

> http://stackoverflow.com/questions/3236194/defining-method-called-how-do-i-make-a-hook-method-which-gets-called-every-t
> 
> に記載されていた
> set_trace_func proc { |event, file, line, id, binding, classname|
>   # only interested in events of type 'call' (Ruby method calls)
>   # see the docs for set_trace_func for other supported event types
>   puts "#{classname} #{id} called" if event == 'call'
> }
> だと、claass name id event で、case等を用いて記述するのがいいのかな…とは
> 思いつつ

set_trace_funcは全てのメソッド呼び出しで呼ばれるので避けたほうがいいでしょう。

> エイリアスチェイニング http://blog.kymmt.com/entry/hook-by-alias-chaining-in-ruby
> 
> だと、多数のmethodがあるので、method内で記述した方がよいし…
> と悩んでおります。

2.0以降ではModule#prependがあるのでalias_method_chainを使うことはない
でしょう。

--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦