Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>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.</p> <p>From high school algebra, you should remember functions like this: <code>f(x) = x + 1</code>.</p> <p>Imagine putting curly braces around the <code>x + 1</code>: <code>f(x) = { x + 1 }</code></p> <p>Then move the <code>(x)</code> to inside the curly braces: <code>f = {(x) x + 1 }</code></p> <p>And then get rid of the name <code>f</code>: <code>{(x) x + 1 }</code>. This makes it an "anonymous function," i.e. a "lambda."</p> <p>Here's the problem: The braces could contain arbitrary statements, which may themselves use parentheses: <code>(x + 1) * 4</code>. So how would Ruby know that the <code>(x)</code> 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: <code>|x|</code>. (At least I assume that was the thought process).</p> <p>So <code>{|i| i &gt; 4 }</code> is just like <code>f(i) = i &gt; 4</code>, 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.</p> <p><code>Array#delete_if</code> 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 <code>[1,2,3,4,5,6,7]</code> into the block as the argument <code>i</code> to see whether <code>i &gt; 4</code> is true for that member. It's equivalent to doing something like this:</p> <pre><code>def greater_than_four(x) x &gt; 4 end arr = [1,2,3,4,5,6,7] arr.each do |el| arr.delete(el) if greater_than_four(el) end </code></pre> <p>You could avoid defining the <code>greater_than_four</code> method in advance by defining a lambda on the fly like this:</p> <pre><code>arr = [1,2,3,4,5,6,7] arr.each do |el| arr.delete(el) if lambda{|i| i &gt; 4}.call(el) end </code></pre> <p>But since <code>Array#delete_if</code> already expects a block, and already knows to call it on each element, you can save yourself a whole lot of code:</p> <pre><code>[1,2,3,4,5,6,7].delete_if{|i| i &lt; 4 } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload