Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby method, Proc, and block confusion

Tags:

I have a couple questions about Ruby's methods, procedures, and blocks that strike me as rather odd. They're not so much about syntax or function as the logic behind the decisions made.

Question 1:

Why is it that blocks can be passed to methods (e.g. each) but they cannot be assigned to a variable?

I know you can pass them around in procedures, i.e. p = Proc.new {...} (accessed with &p), but it doesn't make much sense to make the programmer go through these means.

Question 2:

Why is there a differentiation between methods and procedures?

For instance, I can accomplish the task of defining a function and calling that function in the following two ways:

def square(x)     x**2 end  square(3) => 9 

or

square = lambda {|x| x**2} square.call(3) => 9 

Why the differentiation? In Python for example both defining a function in the standard way and by square = lambda x: x**2 accomplish the same task of creating the function and assigning it to square.

like image 960
David Avatar asked Aug 07 '09 17:08

David


People also ask

What is the difference between block proc and lambda in Ruby?

When using parameters prefixed with ampersands, passing a block to a method results in a proc in the method's context. Procs behave like blocks, but they can be stored in a variable. Lambdas are procs that behave like methods, meaning they enforce arity and return as methods instead of in their parent scope.

How is a block different from a proc?

Procs are objects, blocks are notA proc (notice the lowercase p) is an instance of the Proc class. This lets us call methods on it and assign it to variables. Procs can also return themselves. In contrast, a block is just part of the syntax of a method call.

What is &Block in Ruby?

The &block is a way of sending a piece of Ruby code in to a method and then evaluating that code in the scope of that method. In your example code above it means a partial named cart will be rendered in a div.

How does Proc work 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

Question 1: Blocks are not objects, they are syntactic structures; this is why they cannot be assigned to a variable. This is a privilege reserved for objects.

Question 2: Methods are not objects, so they cannot receive messages. Inversely, procs and lambdas are objects, so they cannot be invoked like methods, but must receive a message that tells them to return a value on the basis of the parameters passed with the message.

Procs and Lambdas are objects, so they can receive the call message and be assigned to names. To summarize, it is being an object that makes procs and lambdas behave in ways you find odd. Methods and blocks are not objects and don't share that behavior.

like image 170
Pinochle Avatar answered Jan 03 '23 10:01

Pinochle


To some extent at least, methods are objects:

class ABC   def some_method   end end ABC.instance_method(:some_method) #=> #<UnboundMethod: ABC#some_method> 

Further to that, there is a built-in class: Method, as documented here.

See also this: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls

Haphazardly <bseg>, it does rather seem to bear out the everything-is-an-object thing. In this particular case, it just appears to take a little more digging to see.

(I really must make an effort to understand this better: I'm starting to think it's fundamental to getting a deeper understanding.)

like image 28
Mike Woodhouse Avatar answered Jan 03 '23 10:01

Mike Woodhouse