Это сокращение для:
survey.map { |s| s.questions }.flatten.compact
Это метод Symbol # to_proc
. Раньше он был частью ActiveSupport Rails, но с тех пор был добавлен в синтаксис Ruby.
Что касается производительности, я написал быстрый тестовый сценарий, чтобы получить представление о влиянии на производительность как в 1.8, так и в 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
Прежде чем дать вам результаты - если вы еще не были уверены, что Ruby 1.9 значительно улучшил скорость в целом, приготовьтесь к тому, что вас поразит.
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)
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)
Во-первых: Ничего себе. Ruby 1.9 работает быстро. Но более важные выводы, которые мы делаем здесь, интересны:
to_proc
явно быстрее. В 1.8 на многократном беге чуть медленнее. Похоже, это указывает на то, что единственное реальное узкое место в производительности - это создание всех этих Proc-объектов. to_proc
явно намного быстрее, чем блоки, независимо от того, сколько раз вы это делаете. В этом случае вы не только получите более чистый код, но и улучшите производительность. В конце концов, неважно, какую версию вы используете, to_proc
явно не является проблемой производительности, чтобы не использовать ее - на самом деле, иногда это ускоряет работу!