[1,2,3,4,5,6,7].delete_if{|i| i < 4 }
For example, in the above, why do you need to put |i| before i < 4?
I'm new to Ruby programming and the purpose of this element escapes me.
This is very basic Ruby syntax for a block. A block can sometimes take parameters which are given between the bars |. In your case:
[1,2,3,4,5,6,7].delete_if { |i| i < 4 }
The delete_if method for the type Array accepts a block as a parameter. When the bock is given, the block accepts the array element as a parameter. So it iterates i over each value within the array in this case. More specifically, an element will be deleted from the array if that element is < 4. The result will be:
[4,5,6,7]
You'll often see documentation for methods for Ruby types which say, for example:
delete_if { |item| block } -> Array
Which means that the method accepts a block with a parameter, the block being some code that uses the parameter, and the output being another array. The method's description explains more detail in the documentation (e.g., Ruby Array).
I recommend reading some Ruby getting started information online or a good introductory book which will explain this in more detail.
You have to put i there for the same reason you would put i in the first line here:
def plus_one(i)
return i + 1
end
You have to name your method argument, which you later use as a local variable in the method.
Ruby blocks are similar to methods, they can also receive arguments, and syntax for declaring them is slightly different: enclosing them in | |.
I've redone my answer, even though the OP's question has already been answered, because I thought of a new way to explain this that may help future SO users with the same question.
From high school algebra, you should remember functions like this: f(x) = x + 1.
Imagine putting curly braces around the x + 1: f(x) = { x + 1 }
Then move the (x) to inside the curly braces: f = {(x) x + 1 }
And then get rid of the name f: {(x) x + 1 }. This makes it an "anonymous function," i.e. a "lambda."
Here's the problem: The braces could contain arbitrary statements, which may themselves use parentheses: (x + 1) * 4. So how would Ruby know that the (x) is supposed to be an argument to the function, and not an expression to execute? Some other syntax had to be used. Hence the vertical bars: |x|. (At least I assume that was the thought process).
So {|i| i > 4 } is just like f(i) = i > 4, except that it has no name and is not defined in advance, so the parameter has to be defined "inside" the function itself, rather than being outside attached to the name.
Array#delete_if expects such a function (called a "block" when it's used like this) and knows what to do with it. It passes each member of the array [1,2,3,4,5,6,7] into the block as the argument i to see whether i > 4 is true for that member. It's equivalent to doing something like this:
def greater_than_four(x)
x > 4
end
arr = [1,2,3,4,5,6,7]
arr.each do |el|
arr.delete(el) if greater_than_four(el)
end
You could avoid defining the greater_than_four method in advance by defining a lambda on the fly like this:
arr = [1,2,3,4,5,6,7]
arr.each do |el|
arr.delete(el) if lambda{|i| i > 4}.call(el)
end
But since Array#delete_if already expects a block, and already knows to call it on each element, you can save yourself a whole lot of code:
[1,2,3,4,5,6,7].delete_if{|i| i < 4 }
The parameter which you are passing to the delete_if method is a block and the thing inside the parameter you pass to the block.
Think of the block as a method of sorts. The delete_if method iterates over the block and passes the current item as the parameter i to the block. If the condition evaluates to true then that element gets deleted.
Related
Consider the following:
(1..10).inject{|memo, n| memo + n}
Question:
How does n know that it is supposed to store all the values from 1..10? I'm confused how Ruby is able to understand that n can automatically be associated with (1..10) right away, and memo is just memo.
I know Ruby code blocks aren't the same as the C or Java code blocks--Ruby code blocks work a bit differently. I'm confused as to how variables that are in between the upright pipes '|' will automatically be assigned to parts of an object. For example:
hash1 = {"a" => 111, "b" => 222}
hash2 = {"b" => 333, "c" => 444}
hash1.merge(hash2) {|key, old, new| old}
How do '|key, old, new|' automatically assign themselves in such a way such that when I type 'old' in the code block, it is automatically aware that 'old' refers to the older hash value? I never assigned 'old' to anything, just declared it. Can someone explain how this works?
The parameters for the block are determined by the method definition. The definition for reduce/inject is overloaded (docs) and defined in C, but if you wanted to define it, you could do it like so (note, this doesn't cover all the overloaded cases for the actual reduce definition):
module Enumerable
def my_reduce(memo=nil, &blk)
# if a starting memo is not given, it defaults to the first element
# in the list and that element is skipped for iteration
elements = memo ? self : self[1..-1]
memo ||= self[0]
elements.each { |element| memo = blk.call(memo, element) }
memo
end
end
This method definition determines what values to use for memo and element and calls the blk variable (a block passed to the method) with them in a specific order.
Note, however, that blocks are not like regular methods, because they don't check the number of arguments. For example: (note, this example shows the usage of yield which is another way to pass a block parameter)
def foo
yield 1
end
# The b and c variables here will be nil
foo { |a, b, c| [a,b,c].compact.sum } # => 1
You can also use deconstruction to define variables at the time you run the block, for example if you wanted to reduce over a hash you could do something like this:
# this just copies the hash
{a: 1}.reduce({}) { |memo, (key, val)| memo[key] = val; memo }
How this works is, calling reduce on a hash implicitly calls to_a, which converts it to a list of tuples (e.g. {a: 1}.to_a = [[:a, 1]]). reduce passes each tuple as the second argument to the block. In the place where the block is called, the tuple is deconstructed into separate key and value variables.
A code block is just a function with no name. Like any other function, it can be called multiple times with different arguments. If you have a method
def add(a, b)
a + b
end
How does add know that sometimes a is 5 and sometimes a is 7?
Enumerable#inject simply calls the function once for each element, passing the element as an argument.
It looks a bit like this:
module Enumerable
def inject(memo)
each do |el|
memo = yield memo, el
end
memo
end
end
And memo is just memo
what do you mean, "just memo"? memo and n take whatever values inject passes. And it is implemented to pass accumulator/memo as first argument and current collection element as second argument.
How do '|key, old, new|' automatically assign themselves
They don't "assign themselves". merge assigns them. Or rather, passes those values (key, old value, new value) in that order as block parameters.
If you instead write
hash1.merge(hash2) {|foo, bar, baz| bar}
It'll still work exactly as before. Parameter names mean nothing [here]. It's actual values that matter.
Just to simplify some of the other good answers here:
If you are struggling understanding blocks, an easy way to think of them is as a primitive and temporary method that you are creating and executing in place, and the values between the pipe characters |memo| is simply the argument signature.
There is no special special concept behind the arguments, they are simply there for the method you are invoking to pass a variable to, like calling any other method with an argument. Similar to a method, the arguments are "local" variables within the scope of the block (there are some nuances to this depending on the syntax you use to call the block, but I digress, that is another matter).
The method you pass the block to simply invokes this "temporary method" and passes the arguments to it that it is designed to do. Just like calling a method normally, with some slight differences, such as there are no "required" arguments. If you do not define any arguments to receive, it will happily just not pass them instead of raising an ArgumentError. Likewise, if you define too many arguments for the block to receive, they will simply be nil within the block, no errors for not being defined.
Ruby provides the #tap method, which allows you to take in a variable and run code on it, but then return the original variable rather than the result of your expression, ie:
def number
5.tap { |x| print x } # Prints 5, and returns 5
end
Is there any function built into Clojure that can provide this functionality?
You're looking for doto. Here's your example, rewritten using it:
(doto 5
println)
It works similarly to the -> macro in that it passes the value through a series of functions. A key difference is that it returns the initial value you passed in, rather than what is returned by the final function.
My code is supposed to print integers in an array.
odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]
ints = odds_n_ends.select { |x| if x.is_a?(Integer) then return x end }
puts ints
It gives me an error in the 2nd line - in 'block in <main>': unexpected return (LocalJumpError)
When I remove the return, the code works exactly as desired.
To find the mistake in my understanding of blocks, I read related posts post1 and post2. But, I am not able to figure out how exactly are methods and blocks being called and why my approach is incorrect.
Is there some call stack diagram explanation for this ? Any simple explanation ?
I am confused because I have only programmed in Java before.
You generally don't need to worry exactly what blocks are to use them.
In this situation, return will return from the outside scope, e.g. if these lines were in a method, then from that method. It's the same as if you put a return statement inside a loop in Java.
Additional tips:
select is used to create a copied array where only the elements satisfying the condition inside the block are selected:
only_ints = odds_n_ends.select { |x| x.is_a?(Integer) }
You're using it as a loop to "pass back" variables that are integers, in which case you'd do:
only_ints = []
odds_n_ends.each { |x| if x.is_a?(Integer) then only_ints << x end }
If you try to wrap your code in a method then it won't give you an error:
def some_method
odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]
ints = odds_n_ends.select { |x| if x.is_a?(Integer) then return true end }
puts ints
end
puts some_method
This code output is true. But wait, where's puts ints??? Ruby didn't reach that. When you put return inside a Proc, then you're returning in the scope of the entire method. In your example, you didn't have any method in which you put your code, so after it encountered 'return', it didn't know where to 'jump to', where to continue to.
Array#select basically works this way: For each element of the array (represented with |x| in your code), it evaluates the block you've just put in and if the block evaluates to true, then that element will be included in the new array. Try removing 'return' from the second line and your code will work:
ints = odds_n_ends.select { |x| if x.is_a?(Integer) then true end }
However, this isn't the most Ruby-ish way, you don't have to tell Ruby to explicitly return true. Blocks (the code between the {} ) are just like methods, with the last expression being the return value of the method. So this will work just as well:
ints = odds_n_ends.select { |x| if x.is_a?(Integer) } # imagine the code between {} is
#a method, just without name like 'def is_a_integer?' with the value of the last expression
#being returned.
Btw, there's a more elegant way to solve your problem:
odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]
ints = odds_n_ends.grep(Integer)
puts ints
See this link. It basically states:
Returns an array of every element in enum for which Pattern ===
element.
To understand Pattern === element, simply imagine that Pattern is a set (let's say a set of Integers). Element might or might not be an element of that set (an integer). How to find out? Use ===. If you type in Ruby:
puts Integer === 34
it will evalute to true. If you put:
puts Integer === 'hey'
it will evalute to false.
Hope this helped!
In ruby a method always returns it's last statement, so in generall you do not need to return unless you want to return prematurely.
In your case you do not need to return anything, as select will create a new array with just the elements that return true for the given block. As ruby automatically returns it's last statement using
{ |x| x.is_a?(Integer) }
would be sufficient. (Additionally you would want to return true and not x if you think about "return what select expects", but as ruby treats not nil as true it also works...)
Another thing that is important is to understand a key difference of procs (& blocks) and lambdas which is causing your problem:
Using return in a Proc will return the method the proc is used in.
Using return in a Lambdas will return it's value like a method.
Think of procs as code pieces you inject in a method and of lambdas as anonymous methods.
Good and easy to comprehend read: Understanding Ruby Blocks, Procs and Lambdas
When passing blocks to methods you should simply put the value you want to be returned as the last statement, which can also be in an if-else clause and ruby will use the last actually reached statement.
Okay, so im reading a guide for ruby and I can't make sense of this code. Where did i come from. I see that n is passed to iterate through the block but I have no idea where I comes from. If I could get a full explanation and breakdown of how this code works that would be great!
class Array
def iterate!
self.each_with_index do |n, i|
self[i] = yield(n)
end
end
end
array = [1, 2, 3, 4]
array.iterate! do |n|
n ** 2
end
i is the index of the element (hence the name, each_with_index).
Some methods that are called with code blocks will pass more than one value to the block, so you end up with multiple block arguments (in your case the block arguments are n and i, which will hold the current item in the array (n) and the index of it (i)).
You can find out how many arguments a block will be passed by looking at the documentation for a method (here's the docs for each_with_index). It does look like the extra values come from nowhere at first, and it takes a little while to memorize what a block will be passed when different methods are called.
i is commonly used as what's known as an "iterative variable". Basically, the loop block that you've copied here goes through each "iteration" of the loop and uses a new value of i and assigns it to the variable n, which is then passed on to the operation at the second to last line. In this case, the new value is simply the next number in array, and so there are four iterations of the loop.
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