Есть ли способ использовать более одного атрибута / метода с оператором амперсанда в двоеточии? - PullRequest
0 голосов
/ 16 октября 2018

Это было бы примерно так: учитывая массив foo объектов с атрибутом bar, который также имеет атрибут с именем baz:

foos.each(&:bar.baz)

, я легко могу получить все bar s с foos.each(&:bar), но атрибут baz (или сколько угодно других) я не могу, так как он дает мне ошибку: TypeError: wrong argument type String (expected Proc)

Ответы [ 4 ]

0 голосов
/ 17 октября 2018

Лучший вариант - просто использовать обычный синтаксис блока:

foos.each { |foo| foo.bar.baz }

Если вы все еще хотите использовать синтаксис типа &:sym, например, потому что имена методов являются динамическими, вы можете проверитьиз Xf драгоценного камня.Это позволяет вам:

foos.each(&Xf.pipe(:bar, :baz))

Функцию можно копировать без включения драгоценного камня, просто заимствуя метод pipe:

def pipe(*fns)
  Proc.new do |target|
    new_value = target
    fns.each { |fn| new_value = fn.to_proc.call(new_value) }
    new_value
  end
end

require 'ostruct'
# openstruct used to emulate objects that would respond to .foo.bar
foos = []
foos << OpenStruct.new(foo: OpenStruct.new(bar: 'hello'))
foos << OpenStruct.new(foo: OpenStruct.new(bar: 'world'))
foos.each(&pipe(:foo, :bar))
0 голосов
/ 16 октября 2018

Возможно ли это с оператором амперсанда и двоеточия

Нет.Прежде всего потому, что не существует понятия «оператор амперсанда».Это

foos.each(&:bar)

- более короткий способ написания этого

sym = :bar
foos.each(&sym)

Также см. Другие ответы для альтернатив.

0 голосов
/ 17 октября 2018

Массив # каждый возвращает своего получателя, так что это может быть не лучшим примером того, что вы ищете.Предположим, у нас есть

arr = [['a', 'b'], ['c', 'd']]

и мы хотим

arr.map(&:first).map(&:upcase)
  #=> ["A", "C"]

Чтобы использовать один амперсанд, можно написать

arr.map(&Proc.new { |e| e.first.upcase })
  #=> ["A", "C"]

&, чтобы преобразовать процесс в блок,вызывая выполнение

arr.map { |e| e.first.upcase }

.

0 голосов
/ 16 октября 2018

Использование .map:

foos.map(&:bar).each(&:baz)

Это превратит ваш массив из foo элементов в массив из bar элементов, что позволит вам вызвать .each начто вместо этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...