Ruby code what does "&:" do here [duplicate] - ruby

This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 5 years ago.
def reverse_words(s)
s.split.map(&:reverse).join(' ')
end
This code reverses each word in a sentence. But I do not understand "&:" in the code. Can someone explain that to me?

map expects a code block that takes one argument. What you would normally do is to call reverse on that argument:
map {|elt| elt.reverse }
With the & syntax you can shorten this to
map(&:reverse)
The colon is there to make a symbol out of the name reverse.

The & means that reverse is referencing a function, not a block.
This method assumes that the caller will pass it a String object.
First the method #splits the string on whitespaces into an array (if the string has no whitespaces it creates an array with the string as the only element)
Calls the Array#map method on the new array and passes it a reference to the String#reverse method.
The & tells the map method that the input is a reference to a method and not a standard block

Related

What does the `&:symb` do? [duplicate]

This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 4 years ago.
I've seen an example of how to sort a string. To sort case insensitively:
str.chars.sort(&:casecmp).join
#=> "ginrSt"
I'm curious about (&:casecmp). I found that for example:
arr.map(&:name)
is shorthand for
arr.map(&:name.to_proc)
which is same with
arr.map{|el| el.name}
I know the & (ampersand) tries to convert symbol to proc, and pass it as a block to a method. I do not understand how this would work for sort method, which is supposed to compare two values. Would it be as follows?
str.chars.sort{|a, b| a.casecmp ;b.casecmp}.join
It wouldn't be helpful since soft needs a block to return an integer and casecmp needs an argument. (Or is it called parameter in that case?) To me, it looks more like this:
str.chars.sort{|a, b| a.casecmp(b)}.join
How does &:casecmp know to take one of |a, b| as a caller and the other one as an argument? I wouldn't guess it that it is an option.
If more than one parameter is passed to your block, the proc created by Symbol#to_proc uses the additional block parameters as parameters to the method call.
http://phrogz.net/symbol-to-proc-with-multiple-arguments
So, what's really happening is, sort(&:casecmp) is converted to:
sort {|a,b| a.casecmp(b) }
because sort takes two parameters.

Use 'puts' with block accepting method over multiple lines [duplicate]

This question already has answers here:
Ruby Print Inject Do Syntax
(3 answers)
Closed 7 years ago.
Let's say I have the following (working) pseudo-code:
puts results.fields.inject('') { |string, key|
lengths[key] = calculate_length(key)
string << format(key)
}
Following the ruby-style-guide I should
Omit parentheses for 'keyword methods', i.e. puts, (which would create }) or end) anyway)
Use do...end for multi-line blocks
However, when replacing {...} with do...end it raises
undefined method `' for :title:Symbol (NoMethodError)
Therefore, is it possible to refactor this code without violenting the guideline?
There is a difference in precedence between {} and do end
If you use do end the block is associated with the puts statement, whereas the braces are associated with the results.field.inject('')
If you want to use do end then you have to remove the ambiguity of association by parentheses. It's one of those "gotchas" where the guidelines are recognized as guidelines, not absolute rules.
See also this answer...
In Ruby, why is a method invocation not able to be treated as a unit when "do" and "end" is used?

How is this "map" working? [duplicate]

This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 9 years ago.
Could you explain what the code below is doing:
resp = s3.list_buckets
puts resp.buckets.map(&:name)
My question is specific to map. I am not able to understand how map is being used here. Also, what does (&:name) mean?
I referred map documentation. However, I'm not able to correlate it with the map in the code above. Per the documentation, Map should be followed by a {}, but it is followed by a () in the code above.
In perl context, map will work on an array/list and will return a new array/list. So, it seems to be doing something similar here as well, but I cannot decode that.
Any pointers to documentation would be helpful.
map is an alias for collect
map(&:name) is shortcut for map {|x| x.name }
map expects a block. & calls to_proc on the object, and passes it as a block and Symbol has to_proc implemented. Refer docs for more info
& of (&:name) means what follows it should be a Proc object and will be converted to a code block.
Since & expects a Proc object, :name will be converted to a Proc object, this is done by calling :name.to_proc.
After :name is converted to a Proc object, & then converts the resulting Proc object to a code block and gives the code block to map.
In summary, there are totally two type conversions occured, one is converting a symbol to a Proc object, the other is converting a Proc object to a code block.

What does method_name(*) mean? [duplicate]

This question already has an answer here:
naked asterisk as parameter in method definition: def f(*)
(1 answer)
Closed 8 years ago.
In the rails code I came across following method definition def initialize(*)
I understand what def foo(*a) means but can't figure out significance of omitting identifier name after *. How do you access any arguments passed to this method?
Here's my guess.
It works because of second line:
def initialize(*)
super
...
end
So the method receives arbitrary number of arguments and passes all of them to super(as you know, super without arguments means take all arguments from original method).
And then in this case the names for arguments are not required.

Ruby * operator before array [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Understanding ruby splat in ranges and arrays
could anyone tell me what the * does in the following piece of code?
line = "name=yabbi;language=ruby;"
Hash[*line.split(/=|;/)]
Thanks.
* is the splat operator. It is used to split an array into a list of arguments.
line.split(/=|;/) returns an array. To create a Hash, each element of the array must be passed as an individual parameter.
it's a splat operator Read about it. Often times you see it used when you want to split up an array to use as parameters of a function.

Resources