Есть ли сокращение для Ruby Blocks?

Меня раздражает следующее подробное письмо на Ruby:

polys.each { |poly| poly.edges.each {|edge| draw edge.start, edge.end } }

(polys является массивом полигонов, ребра - это метод многоугольника, возвращающего массив ребер)

В идеале я хотел бы сократить это до чего-то вроде этого:

polys.each.edges.each { draw _.start, _.end }

Более конкретно я хотел бы знать:

  • Как мы могли написать метод взлома method_missing как с первым каждым? (При вызове с отсутствующим методом перечислитель может вызывать этот метод для каждого элемента, возвращаемого из перечисления)
  • Есть ли способ избавиться от |x| используя любой символ или имя по умолчанию?

1 ответ

Решение

Нет. Ближе всего можно сделать:

polys.flat_map(&:edges).each { |_| draw _.start, _.end }

flat_map преобразует массив в другой массив и сглаживает его в массив одного измерения. Если внутри блока вызывается один метод без параметров, вы можете использовать &:edges ярлык.

Это, как говорится, я бы, вероятно, держать его ближе к вашему первоначальному предложению, так как это более читабельно:

polys.each do |poly| 
  poly.edges.each {|edge| draw edge.start, edge.end }
end

Помните, вы пишете код один раз, но он много читается, поэтому читаемость превосходит краткость.

Другие вопросы по тегам