Попался пересмотр методов в ruby - PullRequest
2 голосов
/ 09 марта 2011

О чем следует помнить при переопределении методов в Ruby? В порядке ли переопределение основных библиотечных методов?

Ответы [ 5 ]

2 голосов
/ 10 марта 2011

Я не слишком много делаю обезьяньих патчей, но слышал, что вместо того, чтобы делать

class String
  def improved_method
    # teh codes
  end
end

Лучше поместить новый метод в модуль, а затем включить модуль

module ImprovedString
  def improved_method
    # teh codes
  end
end

class String
  include ImprovedString
end

упрощает поиск места определения метода, и старая версия все еще существует без необходимости создавать цепочку псевдонимов.

2 голосов
/ 09 марта 2011

проблемы ИМХО:

  • Вы забудете об изменении.
  • Вы скопируете вставку фрагмента из Интернета, что приведет к ошибке измененного поведения иВы будете чесать голову, пока не получите безволосые участки.
  • Другой разработчик придет за вами и будет бороться с ошибкой в ​​течение 3 месяцев, пока не обнаружит ее в одном из патчей обезьяны.Он пойдет в отдел кадров, узнает ваш адрес и покажет вам, почему бы не сделать патчи для обезьян.

Теперь иногда вам нужно патчить обезьяну классом (даже в основной библиотеке, почему бы и нет),Я предлагаю

  • Поместите все ваши обезьяньи патчи в ОДНУ исходную папку.
  • Второе, что вы скажете новому разработчику после «Привет, меня зовут ...», эторасположение этой папки и подробное объяснение того, что делает каждый патч обезьяны.
1 голос
/ 09 марта 2011

Мне нравятся другие ответы. Хотя я должен добавить, что:

Иногда вам может потребоваться переопределить методы только для определенных случаев. Вы можете сделать это, и это делает его более управляемым, чем изменение функциональности для всех объектов определенного класса - при условии, что для отладки используется правильный отладчик:

class << object_instance
  def method_redefinition
    return "method_redefinition"
  end
end
object_instance.method_redefinition => "method redefinition"

Указанный набор функций также может быть инкапсулирован в дополнение, чтобы избежать слишком большого вложения и беспорядочного «определения кода внутри выполнения кода»:

module M
  def method_redefinition
     "method_redefinition"
  end
end
object_instance.extend M
object_instance.method_redefinition => "method_redefinition"
0 голосов
/ 30 октября 2012

Этот крошечный драгоценный камень может быть полезен, если вы столкнулись с проблемами исправления обезьян: (https://github.com/gnovos/ctx). Я изначально написал его для создания более выразительных DSL, позволяя вносить изменения в базовые объекты, не причиняя слишком большого ущерба в другом месте, но, вероятно, его можно использовать для любого количества применений. Он решает некоторые проблемы, связанные с исправлениями обезьян, путем переопределения области видимости в произвольных контекстах, которые могут быть заменены при необходимости.

Если я хочу переопределить метод в каком-то базовом классе (например, в String и т. Д.), Я использую ctx_define вместо «def», а затем заключаю фрагмент кода, который должен использовать новое определение, в блок ctx вот так:

class ::String
  ctx_define :dsl, :+ do |other|
    "#{self[0].upcase}#{self[1..-1]}#{other.capitalize}"
  end
end

puts "this" + "is" + "normal" + "text" + "concatination"
# => thisisnormaltextconcatination

ctx(:dsl) { puts "this" + "is" + "special" + "text" + "concatination" }
# => ThisIsSpecialTextConcatination

Я собрал его всего за несколько минут, так что я не могу дать никаких гарантий о том, насколько он надежен в любом количестве сложных ситуаций, но, похоже, он отлично работает для простых нужд. Посмотрите, если вам интересно, и посмотрите, поможет ли это. :)

0 голосов
/ 09 марта 2011

Вы говорите об исправлении обезьян, и это опасно по следующим причинам согласно wikipedia

Небрежно написано или плохо задокументированные патчи обезьян могут привести к проблемы:

  • Они могут привести к проблемам с обновлением, когда патч делает предположения о исправленный объект, который больше не правда; если продукт вы изменили изменения с новым выпуском это может очень хорошо сломай свой патч. По этой причине патчи обезьяны часто делаются условно, и применяется только если необходимо.
  • Если два модуля пытаются обезопасить один и тот же метод, один из они (в зависимости от того, кто бежит последним) "побеждает" и другой патч не имеет никакого эффекта, если обезьяны не написаны с шаблон как alias_method_chain
  • Они создают несоответствие между исходным кодом на диске и наблюдаемое поведение, которое может быть очень сбивает с толку тех, кто не знает существование пятен.

Даже если исправление обезьян не используется, некоторые видят проблему с наличие функции, так как способность использовать патч обезьяны в язык программирования несовместим с применением строгой инкапсуляции, в соответствии с требованиями объекта модель, между объектами.

Там говорят о более безопасном способе обезьяны патч идет в рубине 2 называется 1020 * изыски *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...