Каков этот &block в Ruby? И как это становится переданным в методе здесь?

Я нашел обходной путь для этого, но я не уверен, почему он работает таким образом:

Мне пришлось добавить удаленную команду с прослушивателем tabchange на tabView.

<p:remoteCommand name="onTabChangeProcess" process="tView, @this"/> 
    <p:tabView activeIndex="#{deleteMe.activeIndex}" id="tView" onTabChange="onTabChangeProcess()">
            <p:ajax event="tabChange" listener="#{deleteMe.onTabChange}" update="tView" process="tView"/>

Это заставило форму работать как ожидалось.

52
задан Flip 10 April 2017 в 01:16
поделиться

6 ответов

Блоки являются основной частью Ruby. Они разделяются либо do | arg0, arg1 | ... конец или {| arg0, arg1, arg2 | ...} .

Они позволяют указать обратный вызов для передачи методу. Этот обратный вызов может быть вызван двумя способами - либо путем захвата это, указав последний аргумент с префиксом & , или используя ключевое слово yield :

irb> def meth_captures(arg, &block)
       block.call( arg, 0 ) + block.call( arg.reverse , 1 )
     end
#=> nil
irb> meth_captures('pony') do |word, num|
       puts "in callback! word = #{word.inspect}, num = #{num.inspect}"
       word + num.to_s
     end
in callback! word = "pony" num = 0
in callback! word = "ynop" num = 1
#=> "pony0ynop1" 
irb> def meth_yields(arg)
       yield(arg, 0) + yield(arg.upcase, 1)
     end
#=> nil
irb> meth_yields('frog') do |word, num|
       puts "in callback! word = #{word.inspect}, num = #{num.inspect}"
       word + num.to_s
     end
in callback! word = "frog", num = 0
in callback! word = "FROG", num = 1
#=> "frog0FROG1"

Обратите внимание, что наш обратный вызов был одинаковым в каждом случае - мы можем удалить повторение, сохраняя наш обратный вызов в объекте, а затем передавая его каждому метод. Это можно сделать с помощью лямбда для захвата обратного вызова в объекте, а затем передается методу, добавляя к нему префикс & .

irb> callback = lambda do |word, num|
       puts "in callback! word = #{word.inspect}, num = #{num.inspect}"
       word + num.to_s
     end
#=> #<Proc:0x0052e3d8@(irb):22>
irb> meth_captures('unicorn', &callback)
in callback! word = "unicorn", num = 0
in callback! word = "nrocinu", num = 1
#=> "unicorn0nrocinu1"
irb> meth_yields('plate', &callback)
in callback! word = "plate", num = 0
in callback! word = "PLATE", num = 1
#=> "plate0PLATE1"

Важно понимать различные варианты использования & здесь в качестве префикса к последнему аргументу функции

  • в определении функции он захватывает любой переданный блок в этот объект
  • при вызове функции, он расширяет данный объект обратного вызова в блок

Если вы посмотрите вокруг, блоки используются повсюду, особенно в итераторах, например Массив # каждый .

93
ответ дан 7 November 2019 в 09:09
поделиться

Это работает так:

@ cart.items.empty? кодирование

: id => "cart" Становится атрибутами в соответствии с соглашением, которое вы может удалить {} в хэше параметров, если он последний.

блок равен

render (: partial => "cart",: object => @cart)

поэтому внутри функции, если тележка пусто, он добавит атрибут style со значением "display: none"

Затем будет создан тег div, заполненный содержимым результата выполнения блока, который будет результатом визуализации корзины частичного просмотра с содержимым @cart.

1
ответ дан 7 November 2019 в 09:09
поделиться

Re attributes = {} , это просто аргумент метода со значением по умолчанию. Поэтому, если вы вызываете hidden_div_if (любой) , то есть передавая только первый аргумент, атрибуты по умолчанию будут иметь пустой хэш.

Это полезно, поскольку упрощает настройку Атрибуты ["стиль"] позже, поскольку атрибуты не нужно сначала инициализировать хешем. (Что, тем не менее, можно сделать просто как (attributes || = {}) ["style"] =… .)


& block лишь немного сложнее.

Методы Ruby могут взять последний аргумент, который является блоком, используя специальный синтаксис метод (args) {| block_args | block_code} . & block в основном захватывает этот блок в переменную block как объект Proc . Таким образом, block - это просто переменная, указывающая на анонимную процедуру здесь.

Когда вызывается более поздний content_tag , и & block передается в качестве последнего аргумента, он расширен в блок, как если бы вызов действительно был content_tag (…) {блок изначально был передан в hidden_if_div}


Так что, возможно, я действительно сбивал с толку. Вам следует найти в Google "аргументы по умолчанию для рубина" и "блоки рубина".

например, если бы вызов действительно был content_tag (…) {блок изначально был передан в hidden_if_div}


Так что, возможно, я действительно запутался здесь. Вам следует найти в Google "аргументы по умолчанию для рубина" и "блоки рубина".

например, если бы вызов действительно был content_tag (…) {блок изначально был передан в hidden_if_div}


Так что, возможно, я действительно запутался здесь. Вам следует найти в Google "аргументы по умолчанию для рубина" и "блоки рубина".

4
ответ дан 7 November 2019 в 09:09
поделиться

& block - это способ отправки фрагмента кода Ruby в метод и последующей оценки этого кода в рамках этого метода. В приведенном выше примере кода это означает, что частично именованная корзина будет отображаться в div. Я думаю, что термин закрытие используется для этого в информатике.

Итак, в вашем примере & block :

<%= render(:partial => "cart", :object => @cart) %>

Хорошее прочтение и объяснение блоков, процессов и lamdas можно найти в блоге Роберта Сосински .

11
ответ дан 7 November 2019 в 09:09
поделиться

Ruby реализует блоки, процедуры и лямбда-выражения, которые в компьютерном сообществе называются замыканиями. Если вы начинаете изучать Ruby, вы быстро столкнетесь с таким кодом.

a = ["dog", "cat", "bird"]
a.alter_each! do |n, i|
  "#{i}_#{n}"
end

Так что здесь происходит?

Мы начинаем с набора имён животных и вызываем alter_each! метод передачи блока. В этом блоке кода мы можем указать, как мы хотим изменить каждый элемент. В нашем примере к каждому имени животного будет добавлена ​​его позиция в массиве. Поскольку alter_each! метод выполняет итерацию по каждому элементу, он выполнит наш блок, передав значение и индекс. Наш блок захватывает эти параметры, добавляет к имени префикс индекса и возвращает результат. Теперь давайте посмотрим на alter_each! метод.

Обратите внимание, что метод не определяет никаких параметров, потому что блок автоматически назначается ключевому слову yield. yield вызывается как функция, передающая значение и индекс каждого элемента в массиве и переопределяющая исходное значение.

class Array
  def alter_each!
    self.each_with_index do |n, i|
      self[i] = yield(n,i)
    end
  end
end

Что делать, если вам нужно передать параметр этому методу?

Вы можете изменить сигнатуру метода, чтобы принимать параметры и, наконец, перехватить блок с параметром, начинающимся с амперсанда. В приведенном ниже примере наш блок будет захвачен с параметром & block, который мы вызовем методом call. Это вместо использования yield

class Array
  def modify_each!(add_one = true, &block)
    self.each_with_index do |n, i|
      j = (add_one) ? (i + 1) : i
      self[i] = block.call(n,j)
    end
  end
end

Полная статья о рубиновых блоках

3
ответ дан 7 November 2019 в 09:09
поделиться

Блоки, процедуры и лямбда-выражения (называемые замыканиями в информатике) являются одними из самых мощных аспектов Ruby, а также одним из наиболее неправильно понимаемых. Вероятно, это связано с тем, что Ruby обрабатывает замыкания довольно уникальным образом. Все усложняется тем, что в Ruby есть четыре различных способа использования замыканий, каждый из которых немного отличается, а иногда и бессмыслен. Есть довольно много сайтов с очень хорошей информацией о том, как закрытие работает в Ruby. Но мне еще предстоит найти хорошее, исчерпывающее руководство.

class Array
  def iterate!(&code)
    self.each_with_index do |n, i|
      self[i] = code.call(n)
    end
  end
end

array = [1, 2, 3, 4]

array.iterate! do |n|
  n ** 2
end

Процедуры, AKA, Procs

Блоки очень удобны и синтаксически просты, однако мы можем захотеть иметь много разных блоков в нашем распоряжении и использовать их несколько раз. Таким образом, повторное прохождение одного и того же блока снова и снова потребовало бы от нас повторения. Однако, поскольку Ruby полностью объектно-ориентирован, с этим можно легко справиться, сохранив повторно используемый код как сам объект. Этот повторно используемый код называется Proc (сокращение от «процедура»).Единственная разница между блоками и процедурами заключается в том, что блок - это процедура, которую нельзя сохранить, и поэтому она является одноразовым решением. Работая с Procs, мы можем начать делать следующее:

class Array
  def iterate!(code)
    self.each_with_index do |n, i|
      self[i] = code.call(n)
    end
  end
end

array_1 = [1, 2, 3, 4]
array_2 = [2, 3, 4, 5]

square = Proc.new do |n|
  n ** 2
end

Lambdas

До сих пор вы использовали Procs двумя способами, передавая их напрямую как атрибут и сохраняя их как переменную. Эти процедуры очень похожи на то, что другие языки называют анонимными функциями или лямбдами. Чтобы сделать вещи более интересными, лямбды также доступны в Ruby. Взгляните:

class Array
  def iterate!(code)
    self.each_with_index do |n, i|
      self[i] = code.call(n)
    end
  end
end

array = [1, 2, 3, 4]

array.iterate!(lambda { |n| n ** 2 })

puts array.inspect

Блоки

Самый распространенный, простой и, возможно, самый «Ruby-подобный» способ использования замыканий в Ruby - это блоки. У них есть следующий знакомый синтаксис:

array = [1, 2, 3, 4]

array.collect! do |n|
  n ** 2
end

puts array.inspect

# => [1, 4, 9, 16]
18
ответ дан 7 November 2019 в 09:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: