Какой смысл "для х в у" в Ruby? - PullRequest
13 голосов
/ 27 июля 2010

Я сейчас изучаю Ruby и RoR, и я столкнулся с этим:

<% for post in @posts %>

в направляющей Rails . Я понял, что идиоматический способ сделать это в Ruby - это:

<% @posts.each do |post| %>

Если есть разница, тогда что это? И если нет никакой разницы, то не лучше ли было бы, чтобы люди из Rails выдвигали правильные идиомы Ruby (а не это, что мне кажется более питоническим)?

Редактировать: Я только что нашел два противоречивых объяснения этого: Учебное пособие говорит, что они одинаковы, за исключением того, что цикл for не создает новую область видимости для локального переменные ", тогда как CS.Auckland.ac.NZ говорит, что for является просто синтаксическим сахаром для эквивалента .each.

Edit2: Рассматриваемый for ... in был для index.html.erb, сгенерированного в app/views/posts с помощью script/generate scaffold. Я сделал быструю проверку, и теперь генерируется синтаксис .each. Я предполагаю, что часть руководства была написана на более ранней стадии разработки рельсов, когда эшафот генерировал for ... in.

Edit3: Теперь я могу подтвердить, что for x in y использовался в Rails 2.2.2, но в 2.3.8 он использует y.each do |x|. Просто чтобы ты знал.

Ответы [ 5 ]

21 голосов
/ 27 июля 2010

Страница обучающей точки верна, for эквивалентна each за исключением разницы в области видимости. Вот демонстрация:

arr = [1,2,3]
arr.each do |x|
  last = x
end
last # NameError

против

arr = [1,2,3]
for x in arr
  last = x
end
last #=> 3

Если вы хотите, чтобы он работал, используя each, вам нужно сделать last = nil перед циклом. Это, как указано в ссылке, потому что блоки начинают новую область, в то время как for нет.

Обратите внимание, что это редко имеет практическое значение, и мало кто об этом знает.

Когда люди используют for в ruby, это чаще всего потому, что они привыкли к тому, что они приходят из других языков - не из-за различий между for и each.

0 голосов
/ 28 июля 2010

Еще одна вещь о for x in y заключается в том, что вы можете сделать for i in 1..5, который будет работать как стандартный цикл, начиная с i = 1 и проходя через i = 5.

.является то, что вы можете использовать диапазон, как 3..8 или x..y, вы не застряли, начиная с нуля, что вы были бы с помощью метода n.times.

0 голосов
/ 28 июля 2010

Вы можете использовать for x in y, если вы пытаетесь выполнить профилирование ruby, и ваша версия ruby-prof не имеет исключения метода .

0 голосов
/ 27 июля 2010

Однажды я разрабатывал функцию создания отчетов в формате PDF для веб-сайта, над которым работал.

Плагин, который я использовал, имел много ограничений. Эти ограничения вынудили меня найти решение, которое было крайне необходимым и процедурным. Я использовал конструкции типа while или for только для того, чтобы подчеркнуть этот стиль программирования.

Фактически, это была единственная ситуация, когда я использовал эти ключевые слова в ruby.

0 голосов
/ 27 июля 2010

Дело в том, что первый пример (for post in @posts) выглядит более «процедурным», а второй (@posts.each do |post|) выглядит более «функциональным». К сожалению, процедурный способ чтения кода по-прежнему считается более популярным, более понятным и менее «отвратительным». Вот почему, возможно, многие предпочли бы его «родному» способу перебора контейнеров.

Если это выглядит питонно (я не уверен, что это правда), то это может считаться даже лучше, так как это улучшает доступность Rails разработчиками из других платформ.

Лично я бы хотел, чтобы рубиновые и "функциональные" способы давили. Но приведенные выше причины показывают, что это можно сделать в любом случае.

...