what does &: mean in ruby, is it a block mixed with a symbol?
When &
used before Proc object in method invocation, it treats the Proc as if it was an ordinary block following the invocation.
When &
used before other type of object (symbol :first_name
in your case) in method invocation, it tries to call to_proc on this object and if it does not have to_proc method you will get TypeError
.
Generally &:first_name
is the same as &:first_name.to_proc
.
Symbol#to_proc Returns a Proc object which respond to the given method by sym.
:first_name.to_proc
will return Proc that looks like this:
proc { |obj, *args, &block| obj.first_name(*args, &block) }
this Proc invokes method specified by original symbol on the object passes as the first parameter and pass all the rest parameters + block as this method arguments.
One more example:
> p = :each.to_proc
=> #<Proc:0x00000001bc28b0>
> p.call([1,2,3]) { |item| puts item+1 }
2
3
4
=> [1, 2, 3]
What does map(&:name) mean in Ruby?
It's shorthand for tags.map(&:name.to_proc).join(' ')
If foo
is an object with a to_proc
method, then you can pass it to a method as &foo
, which will call foo.to_proc
and use that as the method's block.
The Symbol#to_proc
method was originally added by ActiveSupport but has been integrated into Ruby 1.8.7. This is its implementation:
class Symbol
def to_proc
Proc.new do |obj, *args|
obj.send self, *args
end
end
end
what is the functionality of &: operator in ruby?
There isn't a &:
operator in Ruby. What you are seeing is the &
operator applied to a :symbol
.
In a method argument list, the &
operator takes its operand, converts it to a Proc
object if it isn't already (by calling to_proc
on it) and passes it to the method as if a block had been used.
my_proc = Proc.new { puts "foo" }
my_method_call(&my_proc) # is identical to:
my_method_call { puts "foo" }
So the question now becomes "What does Symbol#to_proc
do?", and that's easy to see in the Rails documentation:
Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
# The same as people.collect { |p| p.name }
people.collect(&:name)
# The same as people.select { |p| p.manager? }.collect { |p| p.salary }
people.select(&:manager?).collect(&:salary)
What are :+ and &:+ in Ruby?
Let's start with an easier example.
Say we have an array of strings we want to have in caps:
['foo', 'bar', 'blah'].map { |e| e.upcase }
# => ['FOO', 'BAR', 'BLAH']
Also, you can create so called Proc objects (closures):
block = proc { |e| e.upcase }
block.call("foo") # => "FOO"
You can pass such a proc to a method with the & syntax:
block = proc { |e| e.upcase }
['foo', 'bar', 'blah'].map(&block)
# => ['FOO', 'BAR', 'BLAH']
What this does, is call to_proc on block and then calls that for every block:
some_object = Object.new
def some_object.to_proc
proc { |e| e.upcase }
end
['foo', 'bar', 'blah'].map(&some_object)
# => ['FOO', 'BAR', 'BLAH']
Now, Rails first added the to_proc method to Symbol, which later has been added to the ruby core library:
:whatever.to_proc # => proc { |e| e.whatever }
Therefore you can do this:
['foo', 'bar', 'blah'].map(&:upcase)
# => ['FOO', 'BAR', 'BLAH']
Also, Symbol#to_proc is even smarter, as it actually does the following:
:whatever.to_proc # => proc { |obj, *args| obj.send(:whatever, *args) }
This means that
[1, 2, 3].inject(&:+)
equals
[1, 2, 3].inject { |a, b| a + b }
What exactly is `&:capitalize` in Ruby?
foo(&a_proc_object)
turns a_proc_object
into a block and calls foo with that block.
foo(¬_a_proc_object)
calls to_proc
on not_a_proc_object
and then turns the proc object returned by to_proc
into a block and calls foo with that block.
In ruby 1.8.7+ and active support Symbol#to_proc
is defined to return a proc which calls the method named by the symbol on the argument to the proc.
Ruby ampersand colon shortcut
Your question is wrong, so to speak. What's happening here isn't "ampersand and colon", it's "ampersand and object". The colon in this case is for the symbol. So, there's &
and there's :foo
.
The &
calls to_proc
on the object, and passes it as a block to the method. In Ruby, to_proc
is implemented on Symbol
, so that these two calls are equivalent:
something {|i| i.foo }
something(&:foo)
So, to sum up: &
calls to_proc
on the object and passes it as a block to the method, and Ruby implements to_proc
on Symbol
.
What does the `&` mean in the following ruby syntax?
&:price is shorthand for "use the #price method on every member of the collection".
Unary "&", when passed as an argument into a method tells Ruby "take this and turn it into a Proc". The #to_proc method on a symbol will #send that symbol to the receiving object, which invokes the corresponding method by that name.
What is this &:last Ruby construct called?
This is shorthand for:
survey.map { |s| s.questions }.flatten.compact
It's the Symbol#to_proc
method. It used to be a part of Rails' ActiveSupport, but has since been added to Ruby syntax.
As far as performance goes, I wrote a quick benchmark script to get an idea of performance effect in both 1.8 and 1.9.
require 'benchmark'
many = 500
a = (1..10000).to_a
Benchmark.bm do |x|
x.report('block once') { a.map { |n| n.to_s } }
x.report('to_proc once') { a.map(&:to_s) }
x.report('block many') { many.times { a.map { |n| n.to_s } } }
x.report('to_proc many') { many.times { a.map(&:to_s) } }
end
First off, before giving you the results - if you weren't already sure that Ruby 1.9 was a huge speed improvement in general, prepare to be blown away.
Ruby 1.8 results:
user system total real
block once 0.020000 0.000000 0.020000 ( 0.016781)
to_proc once 0.010000 0.000000 0.010000 ( 0.013881)
block many 6.680000 1.100000 7.780000 ( 7.780532)
to_proc many 7.370000 0.540000 7.910000 ( 7.902935)
Ruby 1.9 results:
user system total real
block once 0.010000 0.000000 0.010000 ( 0.011433)
to_proc once 0.000000 0.000000 0.000000 ( 0.004929)
block many 4.060000 0.000000 4.060000 ( 4.057013)
to_proc many 2.810000 0.000000 2.810000 ( 2.810312)
First off: Wow. Ruby 1.9 is fast. But the more relevant conclusions we draw here are interesting:
- In both cases, for only one run,
to_proc
is clearly faster. In 1.8 on the many-times run, it's tad slower. This seems to indicate that the only real performance bottleneck is creating all those Proc objects. - In Ruby 1.9, however, the
to_proc
method is clearly much faster than blocks, no matter how many times you do it. In this case, you not only get cleaner code, but improved performance, as well.
In the end, no matter which version you're using, to_proc
is clearly not enough of a performance issue to be worth not using - in fact, it sometimes speeds things up!
What does temps.each(&:valid?) mean in Ruby?
The &
is called the to_proc
operator. It expands the symbol (:valid?
) into a Proc.
So your example is equivalent to:
temps.each { |t| t.valid? }
What does this ampersand mean?
It's basically shorthand for this:
[Category, Product, Person].each { |e| e.delete_all }
That is, it sends delete_all
to each element of the iterator.
Related Topics
Combine Array of Array into All Possible Combinations, Forward Only, in Ruby
Windows/Ruby/Rails Install --- .Cannot Load Such File -- SQLite3/Sqlite3_Native Windows
Yaml Indentation for Array in Hash
Ruby Method That Returns Itself
Safe Navigation Operator (&.) for Nil
Ruby - Digest::Digest Is Deprecated; Use Digest
Rails 3 Install Error: "Invalid Value for @Cert_Chain"
How to Create a Hash in Ruby That Compares Strings, Ignoring Case
To_Specs': Could Not Find Chef (>= 0) Amongst [] (Gem::Loaderror)
Calling Sinatra from Within Sinatra
Ruby Minitest: Suite- or Class- Level Setup
Detect If Application Was Started as Http Server or Not (Rake Task, Rconsole etc)