Showing posts with label ruby blocks. Show all posts
Showing posts with label ruby blocks. Show all posts

Thursday, 23 October 2014

What is the difference between Proc and Lambda?

What is the difference between Proc and Lambda?

      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 .

       Procs have block-like behavior and lambdas have method-like behavior. Both, however, are instances of class Proc .

       Creating & invoking procs:
             p = Proc.new {|x,y| x+y }
             p.call(1,2)
       
       Creating & invoking Lamdas:
            succ = lambda {|x| x+1}  =>Ruby1.8
               succ = ->(x){x>0} =>Ruby1.9
                succ.call(1)

        In a lambda-created proc, the return statement returns only from the proc itself
        In a Proc.new-created proc, the return statement is a little more surprising: it returns control not just from the proc, but also from the method enclosing the proc!


      Differences:
        
Procs
Lambda
 A proc is the object form of a block, and it behaves like a block.

 Calling a proc is like yielding to a block.

 A proc is like a block, so if you call a proc that executes a return  statement, it attempts
to return from the method that encloses the block that was converted to the proc.
For Example:

def test
puts "entering method"
p = Proc.new { puts "entering proc"; return }
p.call  # Invoking the proc makes method return
puts "exiting method"  # This line is never executed
end
test

 break to do the same thing like return in a proc.


  proc handles the arguments it receives  flexibly:discarding extras, silently adding nil  for omitted arguments.

   p = Proc.new {|x,y| print x,y }
   p.call(1,2)  # prints 1,2
   p.call(1)  # prints 1, nil
 A lambda has slightly
modified behavior and behaves more like a method than a block.
 whereas calling a lambda is like invoking a method.

 A return  statement in a lambda returns from the lambda itself, not from the method that surrounds the creation site of the lambda:
For Example:
def test
puts "entering method"
p = lambda { puts "entering lambda"; return }
p.call
 # Invoking lambda does not make the method #return
puts "exiting method" 
# This line *is* executed now
end
test

break to do the same thing like return in a lambda.

 Lambdas are not flexible in this way; like methods, they must be invoked with precisely
the number of arguments they are declared with:

         l = lambda {|x,y| print x,y }
         l.call(1,2) # This works
         l.call(1) # Wrong number of arguments

   next statement works the same in a block, proc, or lambda.
   redo also works the same in procs and lambdas.
   retry is never allowed in procs or lambdas: using it always results in a LocalJumpError.
   raise behaves the same in blocks, procs, and lambdas. Exceptions always propagate up the call stack

Wednesday, 18 July 2012

In Ruby 1.9, blocks introduce their own scope

With the latest release of ruby 1.9, blocks introduce their own scope. Below is the example.


x = 1

10.times do |u; x|

x =u
p "value of x - #{x}"

end

p "value of x - #{x}"


In the above case, x is treated as a local variable and we are assigning value of u to x in the loop.


Thank You,

Tuesday, 17 July 2012

no block given (yield) (LocalJumpError)

This error will occur when working with blocks.

When you used the 'yield' statement inside the method and didn't pass block as parameter then it will raise the 'no block given (yield) (LocalJumpError)' error.

def my_method
yield
end

puts my_method

In the above method call we are not passing parameter as a block so it will throw '(LocalJumpError) error'.

Here is the correct way to pass block as a parameter


def my_method
yield
end

puts my_method{puts 'Hi Uma Mahesh'}


Thank You,
Uma Mahesh.