Это плохая идея, чтобы обезьяна патч объекта, чтобы иметь более естественный способ проверки, если элемент находится в массиве? - PullRequest
0 голосов
/ 10 января 2019

Надоело, что в Ruby мы можем проверить, содержит ли массив (или другой Enumerable) значение с помощью метода include? ...

puts %w(one two three four).include?("two")
# => true
puts %w(one two three four).include?("five")
# => false

... но не напрямую проверять, включено ли значение в массив (семантически идентично, но не является частью языка) ...

puts "two".in?( %w(one two three four) )
puts "five".in?( %w(one two three four) )

Я думал, что у обезьяньей заплатки Object есть удобный Object#in? метод, похожий на:

class Object
  def in?(array)
    return false unless array.respond_to?(:include?)  # Or perhaps raise an error.
    return array.include?(self)
  end
end

С этим определением метода на Object, такие вещи, как

"two".in?( %w(one two three four) )
# => true
:nuts.in?( [:banana, :chocolate, :pie] )
# => false

работают хорошо и очень близки к обычному предложению, выражающему этот тест.

Часто я сталкиваюсь с тем, что if element.in?(array) является несколько более естественным выражением, чем if array.include?(element), особенно если массив включен как литерал (вместо ссылки на переменную).

Вопрос (пренебрегая общим мнением об исправлении обезьян): действительно ли этот пример исправления обезьян умная вещь? Каковы конкретные недостатки использования метода Object#in?, опять же, не вдаваясь в общие плюсы и минусы объектов исправления обезьян (в Ruby)?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Игнорируя общие аргументы за / против исправления обезьян в Ruby, код, который вы описываете, является примером удобного метода , который поможет вам с удобочитаемостью. Аргументы против его включения также применимы и к общему случаю, поэтому особого недостатка, по-видимому, нет. Технически, этот метод уже включен в среду Ruby on Rails, поэтому авторы поделились вашим мнением, поддерживая его как естественное выражение.

0 голосов
/ 10 января 2019

Я бы либо потребовал соответствующий модуль Rails Active Support ( core_ext / object /lusion.rb ) в ваш проект, либо, если вы собираетесь изменить Object самостоятельно, используйте тот же исходный код, что и Метод Rails ' Object # in? .

# File activesupport/lib/active_support/core_ext/object/inclusion.rb, line 12
def in?(another_object)
  another_object.include?(self)
rescue NoMethodError
  raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
end
...