У меня просто был быстрый вопрос относительно циклов в Ruby. Существует ли различие между этими двумя способами выполнить итерации через набор?
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
Просто удивление, если это точно то же или если, возможно, существует тонкое различие (возможно, когда @collection
ноль).
Это единственное различие:
each:
irb> [1,2,3].each { |x| }
=> [1, 2, 3]
irb> x
NameError: undefined local variable or method `x' for main:Object
from (irb):2
from :0
for:
irb> for x in [1,2,3]; end
=> [1, 2, 3]
irb> x
=> 3
В цикле for
переменная итератора продолжает жить после завершения блока. В цикле each
- нет, если только она не была определена как локальная переменная до начала цикла.
В остальном, for
- это просто синтаксический сахар для метода each
.
Когда @collection
становится nil
, оба цикла выбрасывают исключение:
Exception: undefined local variable or method `@collection' for main: Object
Ваш первый пример,
@collection.each do |item|
# do whatever
end
более идиоматичен. Хотя Ruby поддерживает такие конструкции циклов, как for
и while
, синтаксис блоков обычно предпочтительнее.
Еще одно тонкое различие заключается в том, что любая переменная, которую вы объявите в цикле for
, будет доступна вне цикла, в то время как переменные в блоке итератора являются частными.
Похоже, нет никакой разницы, для
использует каждый
внизу.
$ irb
>> for x in nil
>> puts x
>> end
NoMethodError: undefined method `each' for nil:NilClass
from (irb):1
>> nil.each {|x| puts x}
NoMethodError: undefined method `each' for nil:NilClass
from (irb):4
Как говорит Баярд, каждый из них более идиоматичен. Он скрывает от вас больше и не требует специальных языковых функций. Комментарий Телемаха
для .. в ..
устанавливает итератор вне области действия цикла, поэтому
for a in [1,2]
puts a
end
оставляет
определенным после завершения цикла. Где, как , каждый
- нет. Это еще одна причина в пользу использования каждого
, потому что временная переменная живет более короткий период.
Насколько я знаю, использование блоков вместо внутриязыковых управляющих структур более идиоматично.
См. « The Evils of the For Loop» для хорошего объяснения (есть одно небольшое различие с учетом диапазона переменных).
Использование каждый
считается более идиоматическим использованием Ruby.