Подтвердить что ты не робот

Может кто-нибудь объяснить Ruby использование символов в блоке?

Может кто-нибудь объяснить мне, что Ruby использует символы трубы в блоке? Я понимаю, что он содержит имя переменной, которому будут присваиваться данные по мере их итерации. Но что это называется? Может ли быть больше одной переменной внутри труб? Что-нибудь еще я должен знать об этом? Любые хорошие ссылки на дополнительную информацию об этом?

Например:

25.times { | i | puts i }
4b9b3361

Ответ 1

Скобки определяют анонимную функцию, называемую блоком. Токены между трубой являются аргументами этого блока. Количество необходимых аргументов зависит от того, как используется блок. Каждый раз, когда блок оценивается, метод, требующий блока, будет передавать значение на основе вызывающего его объекта.

То же, что и определение метода, только он не хранится за пределами метода, который принимает блок.

Например:

def my_print(i) 
  puts i
end

будет делать то же самое, что и при выполнении:

{|i| puts i}

Единственное различие заключается в том, что блок определен "на лету" и не сохраняется.

Пример 2: Следующие утверждения эквивалентны

25.times &method(:my_print)

25.times {|i| puts i}

Мы используем анонимные блоки, потому что большинство функций, передаваемых как блок, как правило, специфичны для вашей ситуации и не требуют определения для повторного использования.

Итак, что происходит, когда метод принимает блок? Это зависит от метода. Методы, принимающие блок, будут вызывать его, передавая значения из своего вызывающего объекта в четко определенном виде. То, что возвращается, зависит от метода, требующего блока.

Например: В 25.times {|i| puts i}.times вызывает блок один раз для каждого значения между 0 и значением его вызывающего объекта, передавая значение в блок как временную переменную i. Times возвращает значение вызывающего объекта. В этом случае 25.

Посмотрите на метод, который принимает блок с двумя аргументами.

{:key1 => "value1", :key2 => "value2"}.each {|key,value| 
     puts "This key is: #{key}. Its value is #{value}"
}

В этом случае каждый вызывает блок для каждой пары ключ/значение, передавая ключ в качестве первого аргумента, а значение - в качестве второго аргумента.

Ответ 2

Трубы определяют аргументы, которые заполняются значениями функцией, вызывающей ваш блок. Их может быть ноль или более, и сколько вы должны использовать, зависит от метода, который вы вызываете.

Например, each_with_index использует две переменные и помещает элемент в один из них, а индекс - в другой.

вот хорошее описание того, как работают блоки и итераторы

Ответ 3

Блочные аргументы следуют всем тем же соглашениям, что и параметры метода (по крайней мере, начиная с 1.9): вы можете определить необязательные аргументы, списки аргументов переменной длины, значения по умолчанию и т.д. Здесь довольно приличное резюме.

Некоторые вещи, о которых нужно знать: поскольку блоки видят переменные в области, в которой они были определены, если вы передадите аргумент с тем же именем, что и существующая переменная, он "тень" - ваш блок увидит пройденный в значении, а исходная переменная не изменится.

i = 10
25.times { | i | puts i }
puts i #=> prints '10'

Будет напечатан "10" в конце. Потому что иногда это желательно поведение, даже если вы не передаете значение (т.е. Хотите, чтобы вы случайно не сбивали переменную из окружения) вы можете указать имена локальных переменных после точки с запятой после списка аргументов:

x = 'foo'
25.times { | i ; x | puts i; x = 'bar' }
puts x #=> prints 'foo'

Здесь "x" является локальным для блока, хотя значение не передается.