Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does instance_eval succeed with a Proc but not with a Lambda?

Tags:

ruby

I have the following class:

class User
  code1 = Proc.new { }
  code2 = lambda { }

  define_method :test do
    self.class.instance_eval &code1
    self.class.instance_eval &code2
  end
end

User.new.test

Why does the secondinstance_eval fail with a wrong number of arguments (1 for 0) error?

like image 986
Nick Vanderbilt Avatar asked Mar 08 '13 22:03

Nick Vanderbilt


People also ask

What is the difference between proc invocation and lambda invocation?

In Ruby, a lambda is an object similar to a proc. Unlike a proc, a lambda requires a specific number of arguments passed to it, and it return s to its calling method rather than returning immediately.

What is proc and lambda in Ruby?

Blocks are syntactic structures in Ruby; they are not objects, and cannot be manipulated as objects. It is possible, however, to create an object that represents a block. Depending on how the object is created, it is called a proc or a lambda.

What is Proc in Ruby?

A Proc object is an encapsulation of a block of code, which can be stored in a local variable, passed to a method or another Proc, and can be called. Proc is an essential concept in Ruby and a core of its functional programming features.


2 Answers

instance_eval is yielding self (User) to the lambda. Lambdas are particular about their parameters - in the same way methods are - and will raise an ArgumentError if there are too few/many.

class User
  code1 = Proc.new { |x| x == User } # true
  code2 = lambda { |x| x == User }   # true

  define_method :test do
    self.class.instance_eval &code1
    self.class.instance_eval &code2
  end
end

Relevant: What's the difference between a proc and a lambda in Ruby?

like image 114
pdoherty926 Avatar answered Oct 17 '22 06:10

pdoherty926


If you still want to use lambda, this code will work:

block = lambda { "Hello" } # or -> { "Hello" }
some_obj.instance_exec(&block)

instance_exec contrary to instance_eval will not supply self as an argument to the given block, so wrong number of arguments (1 for 0) won't be thrown.

Look here for more info.

like image 23
Yury Kaspiarovich Avatar answered Oct 17 '22 06:10

Yury Kaspiarovich