what are procs and lambdas? practical examples please [duplicate] - ruby

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When to use lambda, when to use Proc.new?
(I know it had been asked several times but I couldn't find satisfactory answer)Can somebody please explain Blocks, Procs and Lambdas and why one should be used over other, what are the situation when one should use proc, similar and/or lambda. Also there effect on computer memory. Practical examples please.

Try Robert Sosinski's Tutorial or Learning to Program by Chris Pine.
For more foundation I suggest you read Why’s (poignant) Guide to Ruby. This guide is responsible for creating many of nowadays Ruby's Pro! Make sure to take a look!
Explanation by Joey deVilla
Another important but subtle difference is in the way procs created with lambda and procs created with Proc.new handle the return statement:
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!
Here's lambda-created proc's return in action. It behaves in a way that you probably expect:
def whowouldwin
mylambda = lambda {return "Freddy"}
mylambda.call
# mylambda gets called and returns "Freddy", and execution
# continues on the next line
return "Jason"
end
whowouldwin
=> "Jason"
Now here's a Proc.new-created proc's return doing the same thing. You're about to see one of those cases where Ruby breaks the much-vaunted Principle of Least Surprise:
def whowouldwin2
myproc = Proc.new {return "Freddy"}
myproc.call
# myproc gets called and returns "Freddy",
# but also returns control from whowhouldwin2!
# The line below *never* gets executed.
return "Jason"
end
whowouldwin2
=> "Freddy"
Thanks to this surprising behaviour (as well as less typing), I tend to favour using lambda over Proc.new when making procs.

Related

Ruby Koans: blocks and arguments (test_blocks_can_take_arguments)

Ruby Koans has the following exercise in about_blocks.rb:
def method_with_block_arguments
yield("Jim")
end
def test_blocks_can_take_arguments
method_with_block_arguments do |argument|
assert_equal __, argument
end
end
I know the answer is assert_equal "Jim", argument, but I'm struggling to understand what is happening. Specifically:
Is argument or assert_equal... the block?
What is yield doing given that method_with_block_arguments returns "Jim" without yield?
I think some of the above commenters are correct in saying that you currently don't have a very deep understanding of Ruby, but don't let that discourage you. It just takes time to learn. When I was first learning Ruby, the concept of blocks and their syntax did take some time to wrap my head around. Once you get it the syntax is very simple, but you until you reach that point...
Anywho, this is my attempt to help you out. :)
argument is a block variable. All the stuff between do and end is the block. assert_equal is just a regular method call, nothing to do with blocks.
What yield does is the key to understanding how blocks work. What yield does it that it "yields" control to the calling function. You may think of it as a callback. When you say "yield" in the middle of a function, you are essentially saying "in the middle of this function, I want to allow someone else to plug in their code and make decisions about what should happen." If you use yield with no arguments, no data from your method gets passed back to the caller.
In essence, yield is a way of "yielding" control to somebody else, in this case the caller of your function.
When you call yield with one or more arguments, you are passing data from the your function back up to the caller. So when you say yield("Jim") you are handing the String "Jim" back to whoever calls method_with_block_arguments.
Lastly, you have to understand that in Ruby, methods always return the result of whatever was the last expression in a particular method. That's why you usually don't need an explicit return statement.
For instance, this method will return 42.
def foo
42
end
That's because 42 is a valid expression in Ruby. It's just an identity, but it's valid Ruby, so Ruby just says "okay, you said 42 and that's the last thing in this method declaration. So when people call 'foo' they get 42 back".
I hope this helps. I think at this point you should assume that you're still pretty early on in terms of your Ruby learning, but you're on the right track investigating blocks. Once you get them you'll understand one of the most powerful parts of Ruby.
Is argument or assert_equal... the block?
No, neither argument nor assert_equal is a block, argument is the variable and anything between do and end is the block. assert_equal is a normal method call.
What is yield doing given that method_with_block_arguments returns "Jim" without yield?
Yield is what makes it special. It calls the block (ie. everything between do and end) and executes it. "Jim" is the argument to the block.
Here is a gist that I copied from Paul while I was learning ruby. That should help in learning about closures in ruby.

Procs and Lambdas for what when we have methods

My doubt is pretty much a matter of misunderstanding...
From what I read, a block is a group of code enclosed by {} or do and end.
From my understanding, what a Proc or Lambda does is:
Get this block
Assign the block to a variable
Which means; we don't need to repeat the whole block all the time.
But, what is the difference among a Proc, Lambda and a standard Method? From my understanding, they all work the same way.
There is one crucial difference between Procs (and lambdas) and methods. Procs are objects, methods aren't. And since Ruby is an object-oriented language, where you can only do things with and to objects, that is very important.
So, if you want to pass a piece of code to a method, you need to have an object, and that's what Procs provide.
You can get a proxy object that represents a method via the Object#method method, which will return an instance of the Method class (which duck-types Proc).
Everything in ruby is considered an object. Proc and lambda are fundamentally similar constructs. This topic is highly opinionated as far as usage goes.
The key advantages is that they can be easily passed around into other blocks and the syntax is short and sweet. Consider the following very simple examples:
multiply = Proc.new {|x,y| x*y}
subtract = lambda {|x,y| x-y}
add = ->(x,y) {x+y}
def do_math (opr, *b)
opr.each do |bloc|
puts bloc.call(b[0],b[1])
end
end
do_math([multiply, subtract, add], 10, 5)
# => 50
# => 5
# => 15
puts multiply.call(5,5)
# => 25
puts subtract.call(5,5)
# => 0
puts add.call(5,5)
# => 10
To get a better grasp of what they are, watch this video: An Introduction to Procs, Lambdas and Closures in Ruby
Additionally the documentation has more examples here: http://www.ruby-doc.org/core-2.0.0/Proc.html
I found that this Codecademy section helps with the distinction.

When do you use a block as an object to be passed around? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Most of the examples I see are trivial, and I'm not sure what this adds to the language. I get why you would use blocks in Objective-C for handling callbacks or in Javascript with closures used as callbacks for timers, but I'm not sure what I'd be using blocks for in Ruby. Is it something that could be used instead of a function with something like inject?
Ruby uses blocks all over, it's one of the most ubiquitous features of the language. It is basically an optimised case of a function-as-a-value. A real function object, like in JavaScript is in Ruby an instance of a Proc class. A block is not an object, and thus avoids some of the overheads that objecthood incurs. The reasoning is, in almost all cases where you want to pass a function as an argument, you'll only be passing one, and you'll want to define it right there on the spot, so why not optimise, and make things a bit syntactically nicer?
This is a block:
[1, 2, 3].each do |i|
puts i
end
This is a function:
func = Proc.new do |i|
puts i
end
[1, 2, 3].hypothetical_each(func)
You can see that even defining a functional value involves a block (as a parameter to Proc constructor).
You normally use a block in inject, not a function. You use it in pretty much every loop structure in Ruby (while is very uncommonly used).
You also use blocks to construct domain-specific languages like Sinatra:
get 'index.html' do
"Hello World"
end
or Rspec:
describe "addition" do
it "should add two numbers together" do
(1+2).should equal(3)
end
end
Learn blocks well, because you can't read, nor write Ruby well without them.
The secret to blocks in ruby is held in the nature of ruby's design.
Ruby was designed with an object modal where method calls are sent as 'messages' to the object and return values are responses. In ruby (unlike python and some other languages), functions and methods are NOT object themselves.
Blocks are ruby's way of allowing function-like messages in this modal and are key to how ruby handles iteration in general.
Someone please correct me if I'm wrong but I believe it is in fact impossible to do any iteration in ruby without creating a block or using a while statement
and in fact the for i in object notation is just syntax shorthand for access to the object each method.
ie.
for i in 1..5
#do stuff with i
end
Is executed exactly the same as:
1..5.each do |i|
#do stuff with i
end
By the ruby VM where the Range object 1..5 (which includes the ruby standart lib Enumerable module) yields it's elements to the passed block
Under the hood this operation looks something like this (note this is a simplified version that fails to take into account the ... exclusive and .. inclusive version of range)
class Range
def init(start, end)
#start = start
#end = end
end
def each
i = #start
while i < #end
yield i
i += 1
end
end
end
So when that for loop is called it creates a range object obj = Range.new(1,5) then sends a message to the object obj.send(:each, &block) and inside the each method is use a while loop and yields to the block
TL;DR
Ruby uses block internally as they are critical to it's very design, without them the language itself would not work with it's message => object => response modal.
So you should not ask: "Why should I use blocks?" Because you can't write a ruby program without them.
Instead you should ask: "How is a block in ruby different than a block in Objective-C and Javascript?" Because they ARE a different.
I cant speak for Objective-C but in JavaScript a block is very much an object. It's a container for code that other objects can pick up and use to do whatever it needs to, the block doesnt even have to relate to the object using it.
In ruby a block is more like a set of instruction an object receives in the mail that it uses on itself (which it then passes to the mail man the next time he comes around)

Ruby method, Proc, and block confusion

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.
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.
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.)
Methods are methods — that is, they're actions that an object can take in response to messages. They are not functions.
Blocks are closures — they're functions that close over the enclosing scope. They don't conceptually "belong to" a given object.
In some languages, methods are merely functions that are members of an object, but Ruby does not view them this way. Separating a method from its owning object is more akin to surgery than simple assignment. Ruby takes its object-orientation model from Smalltalk, the granddaddy of modern OO.

Ruby's yield feature in relation to computer science

I recently discovered Ruby's blocks and yielding features, and I was wondering: where does this fit in terms of computer science theory? Is it a functional programming technique, or something more specific?
Ruby's yield is not an iterator like in C# and Python. yield itself is actually a really simple concept once you understand how blocks work in Ruby.
Yes, blocks are a functional programming feature, even though Ruby is not properly a functional language. In fact, Ruby uses the method lambda to create block objects, which is borrowed from Lisp's syntax for creating anonymous functions — which is what blocks are. From a computer science standpoint, Ruby's blocks (and Lisp's lambda functions) are closures. In Ruby, methods usually take only one block. (You can pass more, but it's awkward.)
The yield keyword in Ruby is just a way of calling a block that's been given to a method. These two examples are equivalent:
def with_log
output = yield # We're calling our block here with yield
puts "Returned value is #{output}"
end
def with_log(&stuff_to_do) # the & tells Ruby to convert into
# an object without calling lambda
output = stuff_to_do.call # We're explicitly calling the block here
puts "Returned value is #{output}"
end
In the first case, we're just assuming there's a block and say to call it. In the other, Ruby wraps the block in an object and passes it as an argument. The first is more efficient and readable, but they're effectively the same. You'd call either one like this:
with_log do
a = 5
other_num = gets.to_i
#my_var = a + other_num
end
And it would print the value that wound up getting assigned to #my_var. (OK, so that's a completely stupid function, but I think you get the idea.)
Blocks are used for a lot of things in Ruby. Almost every place you'd use a loop in a language like Java, it's replaced in Ruby with methods that take blocks. For example,
[1,2,3].each {|value| print value} # prints "123"
[1,2,3].map {|value| 2**value} # returns [2, 4, 8]
[1,2,3].reject {|value| value % 2 == 0} # returns [1, 3]
As Andrew noted, it's also commonly used for opening files and many other places. Basically anytime you have a standard function that could use some custom logic (like sorting an array or processing a file), you'll use a block. There are other uses too, but this answer is already so long I'm afraid it will cause heart attacks in readers with weaker constitutions. Hopefully this clears up the confusion on this topic.
There's more to yield and blocks than mere looping.
The series Enumerating enumerable has a series of things you can do with enumerations, such as asking if a statement is true for any member of a group, or if it's true for all the members, or searching for any or all members meeting a certain condition.
Blocks are also useful for variable scope. Rather than merely being convenient, it can help with good design. For example, the code
File.open("filename", "w") do |f|
f.puts "text"
end
ensures that the file stream is closed when you're finished with it, even if an exception occurs, and that the variable is out of scope once you're finished with it.
A casual google didn't come up with a good blog post about blocks and yields in ruby. I don't know why.
Response to comment:
I suspect it gets closed because of the block ending, not because the variable goes out of scope.
My understanding is that nothing special happens when the last variable pointing to an object goes out of scope, apart from that object being eligible for garbage collection. I don't know how to confirm this, though.
I can show that the file object gets closed before it gets garbage collected, which usually doesn't happen immediately. In the following example, you can see that a file object is closed in the second puts statement, but it hasn't been garbage collected.
g = nil
File.open("/dev/null") do |f|
puts f.inspect # #<File:/dev/null>
puts f.object_id # Some number like 70233884832420
g = f
end
puts g.inspect # #<File:/dev/null (closed)>
puts g.object_id # The exact same number as the one printed out above,
# indicating that g points to the exact same object that f pointed to
I think the yield statement originated from the CLU language. I always wonder if the character from Tron was named after CLU too....
I think 'coroutine' is the keyword you're looking for.
E.g. http://en.wikipedia.org/wiki/Yield
Yield in computing and information science:
in computer science, a point of return (and re-entry) of a coroutine

Resources