32323


class_eval, class_exec で 次のような結果になります。(instance_xxxでも同様)

[code]

    class Foo
      def self.abc
        puts 'abc'
      end
    end
    
    aa = lambda { abc }
    bb = proc { abc }
    
    
    Foo.class_eval { abc }
    > abc    <= OK        
    
    Foo.class_eval &aa
    > ArgumentError: wrong number of arguments (given 1, expected 0)  <= NG!!
    
    Foo.class_eval &bb
    > abc  <= OK!!
    
    Foo.class_exec &aa
    > abc  <= OK!!
    
    Foo.class_exec &bb
    > abc  <= OK!!
    
[/code]

lambda を class_eval で 渡したときに ArgumentError がでてしまいます。  
class_exec を使えば問題ないのですが、なぜ、class_eval と lambda
の組み合わせの場合に、ArgumentErrorが発生するのでしょうか？？


CC BY-SA 3.0
2017-02-02T02:53:40.070
32317
2017-02-02T06:34:33.657
6154
question
ruby
Ruby の class_eval、class_exec にブロック、Proc、lambda を渡すときの違いについて


lambdaは引数の扱いが厳密です。

> lambda のほうがより厳密です。引数の数が違っていると（メソッドのように）エラーになります。 Proc.new
> は引数を多重代入に近い扱い方をします。  
>  <https://docs.ruby-lang.org/ja/latest/method/Kernel/m/lambda.html>

引数を取らないlambdaに引数を与えて呼び出すとエラーになります。

[code]

    irb(main):001:0> lambda { }.call(:error)
    ArgumentError: wrong number of arguments (given 1, expected 0)
        from (irb):1:in `block in irb_binding'
        from (irb):1
        from /usr/local/var/rbenv/versions/2.4.0/bin/irb:11:in `<main>'
    
[/code]

Foo.class_evalの場合ブロックの引数としてFooを渡します。  
<https://docs.ruby-lang.org/ja/latest/method/Module/i/class_eval.html>

lambdaは引数の扱いが厳密なのでclass_evalに引数なしのlambdaをブロックとして渡すと、Fooを引数に渡そうとしてArgumentErrorになります。  
例えば以下のように、引数を1つ取るようなlambdaをブロックとして渡した場合はlambdaでもエラーが出ません。

[code]

    aa = lambda { |mod| abc }
    Foo.class_eval(&aa)
    
[/code]


CC BY-SA 3.0
2017-02-02T05:03:41.260
32323
2017-02-02T06:34:33.657
2017-02-02T06:34:33.657
2599
2599
32317
answer