Есть ли короткий способ написать `{| x | х} `?
Мы часто сокращаем блок, используя обозначение &
для символа, подобного этому:
some_array.group_by(&:foo)
Существует ли аналогичный способ сокращения выражений типа {|x| x}
?
some_array.group_by{|x| x}
Если был метод Object#self
, который возвращает self
, то мы можем сделать
some_array.group_by(&:self)
но, к сожалению, такого метода нет. Что касается количества символов, это может быть больше, но читаемость улучшается.
Ответы
Ответ 1
Да. #itself
был реализован в Ruby 2.2.0.
Вы можете получить доступ к обсуждению основной команды Ruby об этой функции здесь.
В качестве интересного аналога предложен метод #ergo
, который даст получателю данный блок.
Если вы еще не обновили до Ruby 2.2.0, вы можете запросить backport #itself
и/или определить #ergo
следующим образом:
class Object
def itself; self end
def ergo
fail ArgumentError, "Block expected!" unless block_given?
yield self
end
end
И затем:
some_array.group_by &:itself
Ответ 2
Хорошо, там нет встроенного, насколько я знаю, но вы можете сделать многоразовый блок идентификации:
id = Proc.new {|x| x}
some_array.group_by(&id)
И если вы действительно хотите, чтобы это была языковая функция:
class Object
def it
Proc.new {|x| x}
end
end
И тогда вы можете сделать
some_array.group_by(&it)
где угодно. Это может привести к аннулированию гарантии.
Ответ 3
Да! Метод Kernel#itself
был добавлен в Ruby 2.2.0. Этот метод просто возвращает объект, на который он был вызван, поэтому вы можете написать:
some_array.group_by(&:itself)
Вы можете увидеть обширное обсуждение этой функции здесь: https://bugs.ruby-lang.org/issues/6373. Патч был представлен Рафаэлем Франсой в сообщении № 53. Вы можете увидеть это в официальном источнике Ruby, посмотрев object.c.
Если вы используете версию Ruby старше 2.2.0, вы можете легко добавить Kernel#itself
в свой проект, поместив этот код где-нибудь в свой проект и убедившись, что это требуется:
module Kernel
def itself
self
end
end if !Kernel.instance_methods.include?(:itself)
Однако обезвреживание части ядра Ruby, как это может быть опасно, и я бы не рекомендовал его, если вы делаете многоразовый код, например драгоценный камень. Вместо этого я бы рекомендовал просто сделать вашу собственную функцию идентификации, как предложено user2246674:
module MyLibrary
IDENT = Proc.new { |x| x }
array.group_by(&IDENT)
end