[ruby-list:49575] define_method内でsuper(*args)を呼ぶとエラーになる

From: Koga Osamu <osak.63@...>
Date: 2013-09-02 16:33:52 UTC
List: ruby-list #49575
古賀といいます。

memoizeというgemを使っていたところ、以下のような現象に遭遇しました。

memoize gemは、インスタンスメソッドに対して同名の特異メソッドでwrapperを
作成し、メソッドのメモ化を行うものです。
このとき、define_methodで定義されたwrapper内で元のメソッドを
super(*args) として呼び出すのですが、引数にfalseを含むとき、次のようなエ
ラーが発生することがあります。

implicit argument passing of super from method defined by 
define_method() is not supported. Specify all arguments explicitly.
(RuntimeError)

以下、検証コードです。

######### ここから #########
class A
  def foo(a, b)
    puts "#{a} #{b}"
  end

  def bar(a, b, c, d, e)
    puts "#{a} #{b} #{c} #{d} #{e}"
  end
end

a = A.new
# memoize gemと同等の処理
(class<<a; self; end).send(:define_method, :foo) do |*args|
  super(*args)
end
(class<<a; self; end).send(:define_method, :bar) do |*args|
  super(*args)
end

a.foo(1, 2)
a.foo(1, false)
a.bar(1, 2, 3, 4, 5)
a.bar(1, 2, false, 4, 5)
# 以下の3つはエラーになる
a.foo(false, true)
a.foo(false, false)
a.bar(1, 2, 3, false, 5)
######### ここまで #########

Rubyのバージョンは
ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-linux]
です。

この挙動はRubyの仕様なのでしょうか、それともバグでしょうか?
もしも仕様なのでしたら、なぜこのような挙動になっているのでしょうか?


-- 
***************************************
* 古賀 理
* Twitter: @osa_k
* e-mail: osak.63@gmail.com
***************************************

In This Thread

Prev Next