class MyClass
extend Forwardable
def_delegators :@broker, :add
def subscribe_in_broker
@subscribers.map(&method(:add))
end
end
В этом примере @subscribers - это Hash, а @broker.add принимает два аргумента: def broker(k,v).
Это вызывает ArgumentError: wrong number of arguments (given 1, expected 2)
Есть ли способ использовать Forwardable или подобное решение без этой проблемы? Как я могу легко делегировать массив с двумя элементами методу, который принимает два аргумента? Что было бы эквивалентно написанию:
def subscribe_in_broker
@subscribers.map{|k,v| add(k,v) }
end
но используя делегирование?

Может показаться, что блок получает 2 аргумента, но на самом деле он получает только один аргумент (массив из 2 элементов). Ruby интерпретирует |x, y|, как если бы это был |(x, y)|. Скобки (которые здесь можно опустить) разрушать единственный аргумент на две части.
Когда вы используете & с методом, он также получает только 1 аргумент, и если вы хотите его деструктурировать, вы должны быть явно, используя набор круглых скобок вокруг x и y:
def add((x,y))
end
Чтобы было ясно, это метод с одним аргументом, который ожидает, что аргумент будет массивом. Например, вы называете это так: add([1, 2])
Примечание: здесь ничего такого связано с делегированием, просто потому, что Ruby предполагает, что вы собираетесь деструктурировать в одном месте, а не в другом.
Можно передать более одного аргумента блоку (или метод, превращенный в процедуру с помощью '&'), но это не то, что делает map.
Для меня не очевидно, почему hash.map { |x,y| add(x, y) } не подходит для ваших целей. Чтобы обойти это, вам нужно будет определить свою собственную функцию map, которая дает 2 аргумента вместо 1, и это кажется излишним для этого.
Спасибо за полезный ответ. Мой был мусором (и я удалил его, чтобы не вводить себя в заблуждение и других).