A deeper look at procs
In this ruby excerpt which iterates over an array, what does the ampersand before the :name symbol mean?
entries = @entries.sort_by(&:name).map do |entry|
The ampersand (&) before the :name symbol in the Ruby excerpt is part of a shorthand syntax for converting a symbol to a proc.
Here's a breakdown of what it does:
-
Symbol to Proc Conversion: The
&tells Ruby to convert the following symbol (namein this case) into a proc. A proc is a block of code that can be passed around as an argument. -
Proc Calls
nameMethod: This proc will then call thenamemethod on each element (entry) in the array during the iteration.
Essentially, it's a concise way to write a block that sorts and then maps the array based on the value of the name attribute of each element.
Here's a more verbose way to achieve the same functionality:
entries = @entries.sort_by { |entry| entry.name }.map do |entry|
# ... do something with entry
end
Both achieve the same result, but the ampersand syntax provides a cleaner and more concise way to write the block.
What is a proc?
In Ruby, a proc is similar to a Lisp anonymous function. Both are blocks of code that you can treat like self-contained units and pass around in your program.
Here's a deeper look at how procs relate to sorting in Ruby:
Procs as Sorting Criteria:
- When you use
sort_byin Ruby, you provide a block of code that specifies the sorting criteria. This block typically takes two arguments, which represent elements being compared in the array. - By using an ampersand (
&) before a method name (like:namein your example), you create a proc that automatically calls that method on each element during the comparison. - In this case, the
&converts:nameinto a proc that sorts the@entriesarray based on the value of thenameattribute for each entry.
Similarities to Lisp Anonymous Functions:
- Like Lisp anonymous functions, Ruby procs allow you to define a small, reusable block of code without formally defining a method.
- Both can be passed around as arguments to other functions, making your code more flexible and modular.
Key Differences:
- Syntax: Lisp anonymous functions typically use a lambda notation. For example, squaring a number:
(lambda (x) (* x x))
while Ruby procs use either a block syntax
{ |x| x * x }
or the ampersand (&) shortcut.
- Scope: In Ruby, procs can access variables from the surrounding scope where they were created (closures). This can be useful for capturing state or context. Lisp anonymous functions generally don't have this capability by default.