Ruby - возможно ли псевдоним метода для оператора безопасной навигации - PullRequest
0 голосов
/ 22 мая 2018

В Ruby 2.3 появился оператор безопасной навигации, однако я считаю, что его синтаксис слишком дискретен, и его можно легко пропустить при кратком сканировании кода.Вместо этого я предпочитаю синтаксис try, так как он выглядит гораздо более очевидным и преднамеренным.

Так что мой вопрос в Ruby 2.3+: есть ли способ для псевдонима или обезьяны-патча для метода оператора безопасной навигации?&. к имени пользовательского метода т.е.s.fast_try(:upcase!).fast_try(:downcase) вместо записи s&.upcase!&.downcase

Основная идея состоит в том, чтобы попытаться улучшить производительность по сравнению с другой реализацией, такой как метод try.Нет, меня не волнуют незначительные различия в поведении между оператором try и безопасной навигацией.Кроме того, я не возражаю против некоторых неясных ограничений аргументов, если их нельзя избежать, просто укажите на них.

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Я создал драгоценный камень для решения этой проблемы на основе информации из этого ответа StackOverflow.

fast_try - это простая методическая оболочка для оператора безопасной навигации.

Особенности / Цели:

  • Использование оператора безопасной навигации (&.) улучшая читабельность
  • Повышение производительности по сравнению с другими реализациями, такими как ActiveSupport # try method
  • Не беспокойтесь о большинстве неясных аргументов / синтаксических ограничений, если их нельзя избежать.Простота и скорость являются ключевыми.
  • Предоставленные методы должны вести себя очень похоже на оператора безопасной навигации.Если вам нужно сохранить точное поведение ActiveSupport, просто установите собственные имена методов для FastTry.
  • Единственная зависимость - это Ruby 2.3+.Для него не требуется Rails / ActiveSupport, но с ним тоже прекрасно работает!

В инициализаторе:

FastTry.method_names = [:try, :custom_try, :try!]
require 'fast_try/apply'

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

str.try(:upcase).try(:downcase)

# the above statement is now equivalent to using the safe navigation operator Ex.
str&.upcase&.downcase
0 голосов
/ 22 мая 2018

Я думаю, вы могли бы пойти с чем-то таким простым, как

class Object
  def fast_try(meth,*args,&block)
    self&.public_send(meth,*args,&block)
  end
end

Например:

["string","STRING","pOw"].map do |s| 
  s.fast_try(:upcase!)
     .fast_try(:chars)
     .fast_try(:find, ->{"No S"}) { |a| a == "S" }
     .fast_try(:prepend, "!")
end
#=> ["!S",nil,"!No S"]

Пока ваш вопрос гласит, "Нет, мне все равноо незначительных различиях в поведении между оператором try и безопасной навигацией. ", учитывая тот факт, что вы написали гем и отметили следующие

Различия между FastTry и ActiveSupport # try

Наша цель - не поддерживать соответствие с версией ActiveSupport метода try.Однако я хочу вести простой список различий.Пожалуйста, создайте PR или Issue, если вы найдете разницу, которая должна быть задокументирована здесь.

Пока ничего не сообщается

Мне кажется благоразумным упомянуть, что есть заметные и потенциально острые,Различия между двумя здесь - это Repl Spec , чтобы показать различия и ради этого ответа, и тот факт, что ссылка может умереть, вывод этой спецификации выглядит следующим образом:

ActiveSupport#try vs. Safe Navigation (&.)
  #try
    handles would be NoMethodError with nil (using #respond_to?)
    does not work on a BasicObject
    behaves like a method call
      with no method name given
        when block_given?
          yields self to a block with arity > 0
          evaluates block with arity == 0 in the context of self
        when no block_given?
          raises an ArgumentError
      with a method_name given
        a non nil object
          uses public_send for message transmission
        nil
          calls NilClass#try and returns nil
  #try!
    does not handle NoMethodError
    does not work on a BasicObject
    behaves like a method call
      with no method name given
        when block_given?
          yields self to a block with arity > 0
          evaluates block with arity == 0 in the context of self
        when no block_given?
          raises an ArgumentError
      with a method_name given
        a non nil object
          uses public_send for message transmission
        nil
          calls NilClass#try and returns nil
  &. (safe navigation)
    does not handle NoMethodError
    raises a SyntaxError with no method name given when block_given?
    raises a SyntaxError with no method name given when no block_given?
    works on a BasicObject
    does not act like a method call
      with a method_name given
        a non nil object
          &. is not called
        nil
          returns nil without a method call
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...