Есть ли в Ruby аргумент блока по умолчанию?

Я только начинаю делать Groovy после того, как в основном занимался рубином.

По умолчанию он имеет «аргумент блока», it, так сказать, официально не являющийся терминологией Groovy, но я новичок в Groovy.

(1..10).each {println(it)}

А что насчет Руби? Могу ли я использовать значение по умолчанию, чтобы мне не приходилось каждый раз делать |my_block_arg|?

Спасибо!

Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
2
0
392
3

Ответы 3

Нет, у вас нет «дефолта» в Ruby.

Хотя вы можете сделать

(1..10).each(&method(:puts))

Эквивалент в Groovy будет (1..10).each this.&println.

Artefacto 14.09.2018 16:57

Как объяснил Андрей Дейнекос ответ, по умолчанию нет. Вы можете установить контекст self, используя BasicObject # instance_eval или BasicObject # instance_exec. Я не рекомендую это делать, поскольку иногда это может привести к неожиданным результатам. Однако, если вы знаете, что делаете, можно сделать следующее:

class Enumerator
  def with_ie(&block)
    return to_enum(__method__) { each.size } unless block_given?
    each { |e| e.instance_eval(&block) }
  end
end

(1..10).each.with_ie { puts self }
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10
#=> 1..10

(1..10).map.with_ie { self * self }
#=> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
(-5..5).select.with_ie { positive? }
#=> [1, 2, 3, 4, 5]

Если вы хотите вызвать один метод, вы также можете использовать (-5..5).select(&:positive?), но когда объекты, которые вы повторяете, имеют фактические атрибуты, это может стоить проблем. Например:

people.map.with_ie { "#{id}: #{first_name} - #{last_name}" }

Имейте в виду, что если у вас есть локальная переменная id, first_name или last_name в области видимости, они используются вместо методов объекта. Это также не совсем работает для хэшей или методов Перечислимый, которые передают более одного аргумента блока. В этом случае self устанавливается в массив, содержащий аргументы. Например:

{a: 1, b: 2}.map.with_ie { self }
#=> [[:a, 1], [:b, 2]]
{a: 1, b: 2}.map.with_ie { self[0] }
#=> [:a, :b]

Начиная с Ruby 2.7, вы можете использовать аргументы нумерованных блоков:

(1..10).each { puts _1 }

Конечно, это не очень хорошо задокументировано; в некоторых ссылках все еще используется @1, но вышеперечисленное проверено на официальной версии 2.7.

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