akmの日記

2007-12-13

moduleでもオーバーライドっぽく

| 16:16

がしたくなったのんだけど、よく考えるとalias_methodとかalias_method_chainを書くのが面倒だったので、簡単に書けるようにしてみました。

class Module
  def chain_with(suffix, &block)
    if block_given?
      suffix = suffix.to_s
      mod = Module.new(&block)
      methods = mod.instance_methods(false).select{|m|self.method_defined?(m)}
      methods.each do |method|
        mod.module_eval do
          alias_method "#{method}_with_#{suffix}", method
          remove_method method
        end
      end
      include(mod)
      methods.each do |method|
        alias_method "#{method}_without_#{suffix}", method
        alias_method method, "#{method}_with_#{suffix}"
      end
      mod
    end
  end
end

こんな感じで使います。

irb(main):022:0> class A
irb(main):023:1>   def foo
irb(main):024:2>    "foo"
irb(main):025:2>   end
irb(main):026:1>   def bar
irb(main):027:2>    "bar"
irb(main):028:2>   end
irb(main):029:1> end
=> nil
irb(main):030:0> A.instance_methods(false).sort
=> ["bar", "foo"]
irb(main):031:0> A.instance_methods(true).sort - Object.methods
=> ["bar", "foo"]
irb(main):032:0> a1 = A.new
=> #<A:0x2eaae50>
irb(main):033:0> a1.foo
=> "foo"
irb(main):034:0> a1.bar
=> "bar"
irb(main):035:0> a1.baz
NoMethodError: undefined method `baz' for #<A:0x2eaae50>
        from (irb):35
irb(main):036:0>
irb(main):037:0* class A
irb(main):038:1>   chain_with :three_times do
irb(main):039:2*     def foo
irb(main):040:3>       foo_without_three_times * 3
irb(main):041:3>     end
irb(main):042:2>     def baz
irb(main):043:3>       'baz'
irb(main):044:3>     end
irb(main):045:2>   end
irb(main):046:1> end
=> #<Module:0x2e9a488>
irb(main):047:0> A.instance_methods(false).sort
=> ["bar", "foo", "foo_without_three_times"]
irb(main):048:0> A.instance_methods(true).sort - Object.methods
=> ["bar", "baz", "foo", "foo_with_three_times", "foo_without_three_times"]
irb(main):049:0> a1.foo
=> "foofoofoo"
irb(main):050:0> a1.bar
=> "bar"
irb(main):051:0> a1.baz
=> "baz"

alias_method_chainとの違いは、alias_methodしたいメソッドが多くても楽ちんってところでしょうか。

TatyanaTatyana2013/11/12 20:53Your's is a point of view where real ineleligtnce shines through.

DavidDavid2013/11/13 10:02You've <a href="http://rcmhekl.com">imesrpsed</a> us all with that posting!

GuadalupeGuadalupe2013/11/14 21:05TYVM you've solved all my prembols http://ipqgjhcvk.com [url=http://luxawqmai.com]luxawqmai[/url] [link=http://egothfiocyl.com]egothfiocyl[/link]

NishaNisha2013/11/16 12:35I thought I'd have to read a book for a <a href="http://qnqfzwtps.com">discvoery</a> like this!

IcolinIcolin2013/11/18 18:53I hate my life but at least this makes it bealebra. http://zoseisfyuag.com [url=http://maotlchlix.com]maotlchlix[/url] [link=http://pmsauk.com]pmsauk[/link]