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

Есть ли короткий способ написать `{| x | х} `?

Мы часто сокращаем блок, используя обозначение & для символа, подобного этому:

some_array.group_by(&:foo)

Существует ли аналогичный способ сокращения выражений типа {|x| x}?

some_array.group_by{|x| x}

Если был метод Object#self, который возвращает self, то мы можем сделать

some_array.group_by(&:self)

но, к сожалению, такого метода нет. Что касается количества символов, это может быть больше, но читаемость улучшается.

4b9b3361

Ответ 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