yield is called once but gives two different results - ruby

Sorry for a silly question.
I'm reading a book to learn Ruby and there is a piece of code tha looks like that:
def make_casserole
puts "Preheat oven to 375 degrees"
ingredients = yield
puts "Place #{ingredients} in dish"
puts "Bake for 20 minutes"
end
make_casserole do
"noodles, celery, and tuna"
end
make_casserole do
"rice, broccoli, and chicken"
end
And the result you'll get:
Preheat oven to 375 degrees
Place noodles, celery, and tuna in dish
Bake for 20 minutes
Preheat oven to 375 degrees
Place rice, broccoli, and chicken in dish
Bake for 20 minutes
Question: Why the reslut looks as it is? They calling "yield" only once to get first one:
make_casserole do
"noodles, celery, and tuna"
end
How does it gets the second? Shouldn't result be like this:
Preheat oven to 375 degrees
Place noodles, celery, and tuna in dish
Bake for 20 minutes

Why Your Code Works As It Does
In Ruby, yield is a language keyword, but a number of objects also implement #yield or yield-like methods. Yield's job is to collaborate with a block. It might help to think of blocks as a sort of anonymous Proc object (which happens to have its own Proc#yield method) that is explicitly or implicitly available to every Ruby method as part of the language syntax.
The do/end keywords also delimit a block, so when you call:
make_casserole do
"noodles, celery, and tuna"
end
this is exactly the same as if you'd used a block-literal such as:
make_casserole { "noodles, celery, and tuna" }
You're then assigning the result of calling the block back to ingredients, and since each call to #make_casserole is returning only a single String, each call can only provide a single result.
Some Alternatives
While you could theoretically make a block yield multiple values, this isn't particularly idiomatic and is really more appropriate for positional arguments. Consider the following:
def make_casserole *ingredients
step = 0
instruction = "%d. %s\n"
puts [
"Preheat oven to 375 degrees",
"Place #{ingredients.join ', '} in dish",
"Bake for 20 minutes"
].map { format instruction, step += 1, _1 }
end
This does everything you currently do (and more), without needing a block at all. However, its behavior is largely hard-coded, which is where blocks can help.
When to Use Blocks
Blocks are most useful when you want to allow some unanticipated action to be defined or performed dynamically at runtime. For example, maybe you want to prepend an arbitrary word to each ingredient that you haven't predefined in your method or in the list of arguments you're passing:
# This method takes arguments, but yields each ingredient
# to the block for processing that wasn't defined by the
# current method.
def make_casserole *ingredients
puts "Preheat oven to 375 degrees"
puts ingredients.map { "Place #{yield _1} in dish" }
puts "Bake for 20 minutes"
end
# Call the method with some ingredients as arguments,
# and then transform the ingredients according to the
# rules defined in the block.
make_casserole('beans', 'rice') do
case _1
when /beans|barley/; "organic #{_1}"
when /rice|potatoes/; "brown #{_1}"
else _1
end
end
This could be done other ways, of course, but what it allows you to do is to defer decisions about how to act on the yielded items until runtime. The method doesn't really know (or care) what the block returns; it just yields each item in turn and lets the block act on the item. You might decide to pass a block that specifies substitutions, colors, levels of ripeness, or whatever else you want, all using the same method but using a different block.
By yielding each item to the block, the method's behavior can be modified on the fly based on the contents of the block. This creates a great deal of flexibility by leaving certain implementation details up to the block rather than the method.

yield yields control to a block. The return value of that block is what your method (in this case make_casserole) gets back from yield.
Consider if we have the block get input from the user:
irb(main):010:0> make_casserole do
irb(main):011:1* puts "Ingredients: "
irb(main):012:1> gets.strip
irb(main):013:1> end
Preheat oven to 375 degrees
Ingredients:
cheese and beans
Place cheese and beans in dish
Bake for 20 minutes
=> nil
The examples you've shown work the way they do because the block just returns a string without doing anything else. Understanding how blocks work is crucial to reading and writing idiomatic Ruby code.

Related

why pass block arguments to a function in ruby?

I'm unclear on why there is a need to pass block arguments when calling a function.
why not just pass in as function arguments and what happens to the block arguments, how are they passed and used?
m.call(somevalue) {|_k, v| v['abc'] = 'xyz'}
module m
def call ( arg1, *arg2, &arg3)
end
end
Ruby, like almost all mainstream programming languages, is a strict language, meaning that arguments are fully evaluated before being passed into the method.
Now, imagine you want to implement (a simplified version of) Integer#times. The implementation would look a little bit like this:
class Integer
def my_times(action_to_be_executed)
raise ArgumentError, "`self` must be non-negative but is `#{inspect}`" if negative?
return if zero?
action_to_be_executed
pred.my_times(action_to_be_executed)
end
end
3.my_times(puts "Hello")
# Hello
0.my_times(puts "Hello")
# Hello
-1.my_times(puts "Hello")
# Hello
# ArgumentError (`self` must be non-negative but is `-1`)
As you can see, 3.my_times(puts "Hello") printed Hello exactly once, instead of thrice, as it should do. Also, 0.my_times(puts "Hello") printed Hello exactly once, instead of not at all, as it should do, despite the fact that it returns in the second line of the method, and thus action_to_be_executed is never even evaluated. Even -1.my_times(puts "Hello") printed Hello exactly once, despite that fact that it raises an ArgumentError exception as the very first thing in the method and thus the entire rest of the method body is never evaluated.
Why is that? Because Ruby is strict! Again, strict means that arguments are fully evaluated before being passed. So, what this means is that before my_times even gets called, the puts "Hello" is evaluated (which prints Hello to the standard output stream), and the result of that evaluation (which is just nil because Kernel#puts always returns nil) is passed into the method.
So, what we need to do, is somehow delay the evaluation of the argument. One way we know how to delay evaluation, is by using a method: methods are only evaluated when they are called.
So, we take a page out of Java's playbook, and define a Single Abstract Method Protocol: the argument that is being passed to my_each must be an object which implements a method with a specific name. Let's call it call, because, well, we are going to call it.
This would look a little bit like this:
class Integer
def my_times(action_to_be_executed)
raise ArgumentError, "`self` must be non-negative but is `#{inspect}`" if negative?
return if zero?
action_to_be_executed.call
pred.my_times(action_to_be_executed)
end
end
def (hello = Object.new).call
puts "Hello"
end
3.my_times(hello)
# Hello
# Hello
# Hello
0.my_times(hello)
-1.my_times(hello)
# ArgumentError (`self` must be non-negative but is `-1`)
Nice! It works! The argument that is passed is of course still strictly evaluated before being passed (we can't change the fundamental nature of Ruby from within Ruby itself), but this evaluation only results in the object that is bound by the local variable hello. The code that we want to run is another layer of indirection away and will only be executed at the point where we actually call it.
It also has another advantage: Integer#times actually makes the index of the current iteration available to the action as an argument. This was impossible to implement with our first solution, but here we can do it, because we are using a method and methods can take arguments:
class Integer
def my_times(action_to_be_executed)
raise ArgumentError, "`self` must be non-negative but is `#{inspect}`" if negative?
__my_times_helper(action_to_be_executed)
end
protected
def __my_times_helper(action_to_be_executed, index = 0)
return if zero?
action_to_be_executed.call(index)
pred.__my_times_helper(action_to_be_executed, index + 1)
end
end
def (hello = Object.new).call(i)
puts "Hello from iteration #{i}"
end
3.my_times(hello)
# Hello from iteration 0
# Hello from iteration 1
# Hello from iteration 2
0.my_times(hello)
-1.my_times(hello)
# ArgumentError (`self` must be non-negative but is `-1`)
However, this is not actually very readable. If you didn't want to give a name to this action that we are trying to pass but instead simply literally write it down inside the argument list, it would look something like this:
3.my_times(Object.new.tap do |obj|
def obj.call(i)
puts "Hello from iteration #{i}"
end
end)
# Hello from iteration 0
# Hello from iteration 1
# Hello from iteration 2
or on one line:
3.my_times(Object.new.tap do |obj| def obj.call; puts "Hello from iteration #{i}" end end)
# Hello from iteration 0
# Hello from iteration 1
# Hello from iteration 2
# or:
3.my_times(Object.new.tap {|obj| def obj.call; puts "Hello from iteration #{i}" end })
# Hello from iteration 0
# Hello from iteration 1
# Hello from iteration 2
Now, I don't know about you, but I find that pretty ugly.
In Ruby 1.9, Ruby added Proc literals aka stabby lambda literals to the language. Lambda literals are a concise literal syntax for writing objects with a call method, specifically Proc objects with Proc#call.
Using lambda literals, and without any changes to our existing code, it looks something like this:
3.my_times(-> i { puts "Hello from iteration #{i}" })
# Hello from iteration 0
# Hello from iteration 1
# Hello from iteration 2
This does not look bad!
When Yukihiro "matz" Matsumoto designed Ruby almost thirty years ago in early 1993, he did a survey of the core libraries and standard libraries of languages like Smalltalk, Scheme, and Common Lisp to figure out how such methods that take a piece of code as an argument are actually used, and he found that the overwhelming majority of such methods take exactly one code argument and all they do with that argument is call it.
So, he decided to add special language support for a single argument that contains code and can only be called. This argument is both syntactically and semantically lightweight, in particular, it looks syntactically exactly like any other control structure, and it is semantically not an object.
This special language feature, you probably guessed it, are blocks.
Every method in Ruby has an optional block parameter. I can always pass a block to a method. It's up to the method to do anything with the block. Here, for example, the block is useless because Kernel#puts doesn't do anything with a block:
puts("Hello") { puts "from the block" }
# Hello
Because blocks are not objects, you cannot call methods on them. Also, because there can be only one block argument, there is no need to give it a name: if you refer to a block, it's always clear which block because there can be only one. But, if the block doesn't have methods and doesn't have a name, how can we call it?
That's what the yield keyword is for. It temporarily "yields" control flow to the block, or, in other words, it calls the block.
With blocks, our solution would look like this:
class Integer
def my_times(&action_to_be_executed)
raise ArgumentError, "`self` must be non-negative but is `#{inspect}`" if negative?
return enum_for(__callee__) unless block_given?
__my_times_helper(&action_to_be_executed)
end
protected
def __my_times_helper(&action_to_be_executed, index = 0)
return if zero?
yield index
pred.__my_times_helper(&action_to_be_executed, index + 1)
end
end
3.my_times do
puts "Hello from iteration #{i}"
end
# Hello from iteration 0
# Hello from iteration 1
# Hello from iteration 2
0.my_times do
puts "Hello from iteration #{i}"
end
-1.my_times do
puts "Hello from iteration #{i}"
end
# ArgumentError (`self` must be non-negative but is `-1`)
Okay, you might notice that I simplified a bit when I wrote above that the only thing you can do with a block is call it. There are two other things you can do with it:
You can check whether a block argument was passed using Kernel#block_given?. Since blocks are always optional, and blocks have no names, there must be a way to check whether a block was passed or not.
You can "roll up" a block (which is not an object and doesn't have a name) into a Proc object (which is an object) and bind it to a parameter (which gives it a name) using the & ampersand unary prefix sigil in the parameter list of the method. Now that we have an object, and a way to refer to it, we can store it in a variable, return it from a method, or (as we are doing here) pass it along as an argument to a different method, which otherwise wouldn't be possible.
There is also the opposite operation: with the & ampersand unary prefix operator, you can "unroll" a Proc object into a block in an argument list; this makes it so that the method behaves as if you had passed the code that is stored inside the Proc as a literal block argument to the method.
And there you have it! That's what blocks are for: a semantically and syntactically lightweight form of passing code to a method.
There are other possible approaches, of course. The approach that is closest to Ruby is probably Smalltalk. Smalltalk also has a concept called blocks (in fact, that is where Ruby got both the idea and the name from). Similarly to Ruby, Smalltalk blocks have a syntactically light-weight literal form, but they are objects, and you can pass more than one to a method. Thanks to Smalltalk's generally light-weight and simple syntax, especially the keyword method syntax which intersperses parts of the method name with the arguments, even passing multiple blocks to a method call is very concise and readable.
For example, Smalltalk actually does not have an if / then / else conditional expression, in fact, Smalltalk has no control structures at all. Everything is done with methods. So, the way that a conditional works, is that the two boolean classes TrueClass and FalseClass each have a method named ifTrue:ifFalse: which takes two block arguments, and the two implementations will simply either evaluate the first or the second block. For example, the implementation in TrueClass might look a little bit like this (note that Smalltalk has no syntax for classes or methods, instead classes and methods are created in the IDE by creating class objects and method objects via the GUI):
True>>ifTrue: trueBlock ifFalse: falseBlock
"Answer with the value of `trueBlock`."
↑trueBlock value
The corresponding implementation in FalseClass would then look like this:
FalseClass>>ifTrue: trueBlock ifFalse: falseBlock
"Answer with the value of `falseBlock`."
↑falseBlock value
And you would call it like this:
2 < 3 ifTrue: [ Transcript show: 'yes' ] ifFalse: [ Transcript show: 'no' ].
"yes"
4 < 3 ifTrue: [ Transcript show: 'yes' ] ifFalse: [ Transcript show: 'no' ].
"no"
In ECMAScript, you can simply use function definitions as expressions, and there is also lightweight syntax for functions.
In the various Lisps, code is just data, and data is code, so you can just pass the code as an argument as data, then inside the function, treat that data as code again.
Scala has call-by-name parameters which are only evaluated when you use their name, and they are evaluated every time you use their name. It would look something like this:
implicit class IntegerTimes(val i: Int) extends AnyVal {
#scala.annotation.tailrec
def times(actionToBeExecuted: => Unit): Unit = {
if (i < 0) throw new Error()
if (i == 0) () else { actionToBeExecuted; (i - 1).times(actionToBeExecuted) }
}
}
3.times { println("Hello") }
// Hello
// Hello
// Hello

can somebody explain how does the following code execute?

I am following a linked tutorial from the Odin project, its about blocks and procs in ruby. I can't quite understand how does the following code work.
class Array
def eachEven(&wasABlock_nowAProc)
# We start with "true" because arrays start with 0, which is even.
isEven = true
self.each do |object|
if isEven
wasABlock_nowAProc.call object
end
isEven = (not isEven) # Toggle from even to odd, or odd to even.
end
end
end
['apple', 'bad apple', 'cherry', 'durian'].eachEven do |fruit|
puts 'Yum! I just love '+fruit+' pies, don\'t you?'
end
# Remember, we are getting the even-numbered elements
# of the array, all of which happen to be odd numbers,
# just because I like to cause problems like that.
[1, 2, 3, 4, 5].eachEven do |oddBall|
puts oddBall.to_s+' is NOT an even number!'
end
Is ['apple', 'bad apple', 'cherry', 'durian'] a block in this context and are we calling the method isEven on that block?
Does isEven used to only return true or false and if true the following code will be executed?
do |fruit|
puts 'Yum! I just love '+fruit+' pies, don\'t you?'
end
Also, what is this line doing?
self.each do |object|
if isEven
wasABlock_nowAProc.call object
end
end
If isEven is true then call [1, 2, 3, 4, 5] with the object??? What does calling that block with object mean?
Let's do it in parts:
1)The class Array was native from ruby, which means we are adding a method to all instances of Array, the method is the eachEven.
2) This method receives as parameter a block to be executed, keep this information in mind.
3) The ["apple", "bad apple", "cherry"] is an instance from Array, which means that we can execute the method eachEven for this array:
array = ["apple", "bad apple", "cherry"]
array.eachEven do |something|
# The do/end block is the parameter passed to the method `eachEven`
# the block will be binded in `wasABlock_nowAProc` in this case
end
4) Inside the method eachEven we get the self (self is the array itself) and execute another method from the Array instance: each (this method iterate over the array binding the current position to the variable inside brackets: |object|)
5) If the condition returns a positive result, it will execute the block inside if, in the case:
wasABlock_nowAProc.call object
# We execute the block of step 2 passing the current position value as a parameter
In fact, if we execute the following code:
array = [1, 2, 3, 4]
array.eachEven do |position_value|
puts "The #{position_value} is even"
end
We gonna get the following result:
The 1 is even # The block `wasABlock_nowAProc` will bind the 1 to the object and print it
The 3 is even # Same here, 3 will be used as the object in the execution of `wasABlock_nowAProc`
Hope it helps
Let's break apart the code here:
['apple', 'bad apple', 'cherry', 'durian'].eachEven do |fruit|
puts 'Yum! I just love '+fruit+' pies, don\'t you?'
end
What we have here boils down to:
receiver.method do |block_argument_one|
# this is the _body_ of the _block_
end
So:
['apple', 'bad apple', 'cherry', 'durian'] is called the receiver (or subject, or just object or instance)
eachEven is the method being called on the receiver
Everything from do to end is the block. It could also be { to } and work the same (well, mostly)
|fruit| is the block arguments list, with fruit being the only argument the block cares about.
puts … is the body of the block
What happens to the block is:
The code in the block gets interpreted, but not run
A placeholder for that code is passed to the method the block is attached to
the method runs, and can access the block while running
Now lets look at how a method that takes a block works:
class SomeClass
def some_method(regular_argument, &block_capture_argument)
# method body
# explicitly call the block:
block_capture_argument.call("first value passed to block")
# implicitly call the block (same as above)
yield "first value passed to block"
end
end
This shows several ways a block can be used:
When you define a method with the last argument beginning with &, a reference to the block is made available to the method by the name after the & (your wasABlock_nowAProc argument, for example). Then your method can do what is likes with the block, maybe calling it, or maybe even storing it somewhere a completely different method can use it.
Alternatively, you can use the yield keyword to call the block implicitly. In that case, you don't need a & argument to the method (but it still works if you do have that argument). Note that ruby allows you to attach a block to any method, regardless of if it uses that block. Methods can check if there was a block with the keyword block_given?, or check that the value of the & argument is present.
When you call the block, either with yield or with call, arguments you give to the call method are passed as arguments to the block.
The method can do whatever it wants with the block. It can call it once, twice, 0, or 300 times. It can call it with the same arguments each time or with different arguments each time.
In your specific example, the block gets called (with the value of object) for each item in the receiver, but only if the isEven variable is true.
Also in your specific example, you are calling the block from inside another block (which provides object for you), but don't let that confuse you.
To summarize:
blocks can be attached to any method using either do … end or {…}
blocks don't run unless the method they are attached to decides to call them
methods get called on a receiver
methods that use blocks get to decide how and when to use them
methods that use blocks can call blocks (or use yield) and pass any number of arguments to the block.
blocks can be defined to use those arguments (with the |…| syntax), and can name those arguments whatever they want (what matters is the order/position of the arguments).

What's the difference between `puts` and `return` result?

When I run the following code:
class GermanShepard
attr_accessor :name
def bark
puts "Loud Bark"
end
end
max = GermanShepard.new
max.name = "Max"
puts "#{max.name} goes #{max.bark}"
the result is:
Loud Bark
Max goes
When I change puts to return at the GermanShepard. It gives:
Max goes Loud Bark
I don't understand the difference between the two command in the class.
Expression
In most languages, return in a method means giving a value to the caller.
In Ruby, everything is an expression. In an essence, the last line of a method is automatically called with return. As an example, the following methods are equivalent:
def bark_a
'Woof!'
end
def bark_b
return 'Woof!'
end
However, some methods may not be returning anything.
def bark_c
end
In this case, ruby is actually returning a nil object. An example would be the
puts method. The puts method simply displays whatever you've given it.
So in your example,
def bark
puts "Loud Bark"
end
is actually doing 2 things.
It's calling the puts method (displaying Loud Bark to the terminal screen)
then it's giving a nil value back to the method caller.
You can try running puts nil and see what's printed out!
"#{}"
Calling #{} in ruby is called interpolation, which is basically putting the variables together in their closest string representation value. The following statements are roughly equivalent:
puts "One plus one equals #{1 + 1}"
puts "One plus one equals " + (1 + 1).to_s
Your example
With all the information above, we can now go through your example step-by-step.
The line puts "#{max.name} goes #{max.bark}" can be separated into a few steps
Calls the name method
The value returned is converted into the closest string representation (In this case we don't need to do anything since name is already a string)
The value is then saved to a temporary variable
At this point, our temporary variable is Max goes.
Calls the bark method
The line puts "Loud Bark" gets executed since we're calling it in the bark method.
Terminal(console) displays "Loud Bark"
Since the puts method returns a nil value, the bark method is also going to return a nil value because it's the last line of the bark method. (Read "Expression" above)
nil is then converted to the closest string representation (which is "")
It is then saved to a temporary variable
The temporary variable is now Max goes
Now, the temporary variable is passed into the puts method, and the terminal(console) displays "Max goes "
Program finishes
Therefore, your example prints out
Loud Bark
Max goes
However, if we change the puts inside the bark method to return,
Step 6 will not happen.
Instead of returning a nil value in step 7, it will return "Load bark"
Step 8 will not happen since "Loud bark" already a string value
and the temporary value after step 9 will become Max goes Loud bark
Hope this helps!
Ray's answer is probably correct, but since it is too verbose (and I didn't even feel like reading it), I will post a concise answer.
There are two things to have in mind.
All arguments passed to a method are evaluated prior to the method call.
All methods in Ruby have a return value. In addition, some methods have side effect, an example of which is to output on the terminal. In any case, returning a value is done after a method has done all its side effects.
With your code as is, the argument of puts in
puts "#{max.name} goes #{max.bark}"
is first evaluated. In order to do so, max.bark (among other things like max.name) would have to be evaluated in advance. The method bark prints "Loud Bark", then returns nil. So the argument mentioned above becomes "#{"Max"} goes #{nil}", and eventually to "Max goes ". That is printed after "Loud Bark".
When you change the puts in the method to return, the method bark will have no side effect, and returns "Loud Bark"; that is the function of return (and by the way, return is not a method but is a keyword). So the argument mentioned above becomes "#{"Max"} goes #{"Loud Bark"}", and eventually to "Max goes Loud Bark". That would be the only thing printed.
puts(string) in ruby writes the string value into $stdout. For example if you run ruby console in terminal, string will be written into your terminal. At the same time every method in ruby returns something and method puts returns nil. So, when we want to interpolate string like "Hello #{some_method}" it will interpolate a returning value of some_method, in case of puts it will interpolate nil value.
Loud Bark # output of max.bark method
Max goes # output of last puts
puts "Loud Bark" # => returns nil
return "Loud Bark" # => returns "Loud Bark"

rspec - how can I refer to a let variable in the it description

I have specs that have:
describe "can translate" do
let(:from){591}
it "#{from}" do
expect(Translator.three_digits(from)).to eq 'five hundred ninety two'
end
end
but 591 is hard-coded and repeated which I want to eliminate...
so how can I refer to from in the it description?
I tried having let(:from){591}
and then using it "#{#from}" but that doesn't show it
I also tried using it "#{from}" but that gives an error undefined local variable or method
'from' for #<Class:0x00000001bc4110> (NameError) as it's looking for a locally scoped variable.
I can avoid all these scope issues with constants, i.e.
describe "can translate" do
FROM=592
it "#{FROM}" do
expect(Translator.three_digits(FROM)).to eq 'five hundred ninety two'
end
end
With that when I get an eror I actually get A ruby file called translator.rb can translate 591 (or whatever number, the key this is that it prints out unlike all my attempt with the variable).
`
but this seems like a poor approach. I prefer to avoid constant when possible and I want to do this test for several values in a row, so I need something I can change from case to case and a CONSTANT seems inappropriate.
I also tried before :all with both local and instance variables but with no success.
If I hard code the it and literally put 591 as the text and the test fails then the 591 prints out which is what I want. However I cannot get the same result working though any variable that I also use in the test.
If you want to run same test for several values, you can do:
values = [100,200,300]
values.each do |value|
it "#{value} do
... # use value here
end
end
The reason why you couldn't do this the way you tried was that it is a class method, and lets defines an instance method. Also note, that if you use let multiple times you will override previous method definition with new one. Since rspec first reads all the tests definitions and then executes them, they all will be run with the same method defined with let. Hence this will not work as expected:
values = [100,200,300]
values.each do |value|
let(:from) { value }
it "#{value} do
puts from
end
end
The above will input 300 three times.
You can add Ruby code within the describe block to define a collection which then can be enumerated to produce multiple examples, e.g.:
describe "can translate" do
translations = [
{input: 591, output: "five hundred ninety one"},
{input: 592, output: "five hundred ninety two"}
]
translations.each do |t|
context "when input is #{t[:input]}" do
it "translates to #{t[:output]}" do
expect(Translator.three_digits(t[:input])).to eq t[:output]
end
end
end
end
I'm trying (and succeeding with) local variables like this:
...
describe "can translate" do
from=738
it from do
expect(Translator.three_digits from).to eq 'seven hundred thirty eight'
end
end
describe "can translate" do
from=592
it from do
expect(Translator.three_digits(from)).to eq 'five hundred ninety two'
end
end
...
describe "can translate" do
subject { Translator.three_digits(from) }
let(:from){|e| e.description.to_i}
it "592" do
is_expected.to eq 'five hundred ninety two'
end
# or
specify("593"){ is_expected.to eq 'five hundred ninety three' }
end

What exactly are anonymous functions?

In my journey of a thousand lines of Ruby, I'm having a really hard time with the concept of anonymous functions. Wikipedia says something about there being some nameless soul in the code and it submitting to a higher order, but my understanding ends there.
Or in other words, how would I (when I understand it) explain anonymous functions to my mom?
An anonymous function has these characteristics:
It has no name (hence anonymous)
Is defined inline
Used when you don't want the overhead/formality of a normal function
Is not explicitly referenced more than once, unless passed as an argument to another function
Here's one example of an anonymous function in Ruby (called a block in this case):
my_array.each{ |item| puts item }
Where's the anonymous function in the above? Why, it's the one that receives a single parameter, names it 'item', and then prints it. In JavaScript, the above might be written as...
Array.prototype.each = function(anon){
for (var i=0,len=this.length;i<len;++i) anon(this[i]);
};
myArray.each(function(item){ console.log(item); });
...which both makes it a little bit more clear that a function is being passed as an argument, and also helps one appreciate Ruby's syntax. :)
Here's another anonymous function (back in Ruby):
def count_to(n)
puts "I'm going to count to #{n}"
count = lambda do |i|
if (i>0)
count[i-1]
puts i
end
end
count[n]
puts "I'm done counting!"
end
count_to(3)
#=> I'm going to count to 3
#=> 1
#=> 2
#=> 3
#=> I'm done counting!
Although the example is obviously contrived, it shows how you can create a new function (in this case named count) and assign it to a variable, and use that for recursive calls inside a master method. (Some feel that this is better than creating a second method just for the recursion, or re-using the master method for recursion with very different parameters.)
The function doesn't have a name, the variable does. You could assign it to any number of variables, all with different names.
Returning to the first example, there's even a syntax in Ruby for passing a lambda as the single, blessed block:
print_it = lambda{ |item| puts item }
%w[a b c].each(&print_it)
#=> a
#=> b
#=> c
...but you can also pass a lambda as a normal parameter and call it later, as illustrated here:
module Enumerable
def do_both_to_each( f1, f2 )
each do |item|
f1[item]
f2[item]
end
end
end
print_prefix = lambda{ |i| print "#{i}*#{i} -> " }
print_squared = lambda{ |i| puts i*i }
(1..4).do_both_to_each(print_prefix,print_squared)
#=> 1*1 -> 1
#=> 2*2 -> 4
#=> 3*3 -> 9
#=> 4*4 -> 16
In addiction to previous answers, the anonymous functions are very usefull when you working with closures:
def make_adder n
lambda { |x|
x + n
}
end
t = make_adder 100
puts t.call 1
Or (in Ruby 1.9):
def make_adder_1_9 n
->(x) {
x + n
}
end
t_1_9 = make_adder_1_9 100
puts t_1_9.call 1
Just as Wikipedia says: a function with no name.
It means that you cannot invoke the function in the typical way, by using its name and parameters. Rather the function itself is usually a parameter to another function. A function that operates on functions is called a "higher order function".
Consider this JavaScript(I know you tagged this ruby but...):
window.onload=function(){
//some code here
}
The function will execute when the page loads, but you cannot invoke it by name, because it does not have a name.
What is the point of an anonymous method?
Explanation by Analogy:
When I order my favourite burger (a greasy Big Nac), I don't want to spend 5 minutes filling out a formal order application: name, address, phone number etc. I ain't got time for that. I want to use my mouth: "give me a burger", nice and quick and easy.
Anonymous methods are kinda like the same thing, except when coding:
It's kinda like throwaway method allowing you to code faster
It's the same when coding. If you have to define a function, you have to put it somewhere (else), you have to call it something, and that's a pain, especially if you know you'll never, ever need it again. And when you read the code, you might have to use a complicated IDE to find that method again, and a reference to it. What a pain! You need a throwaway method that you can write directly in your code, where you need it, and just get it done, and move one. Anonymous methods solve this particular problem.
Anonymous functions have the following characteristics:
No name
Inline declaration
Executed directly when declared

Resources