Ruby Предпочитаемый метод для добавления модулей в библиотечный код? - PullRequest
0 голосов
/ 20 октября 2011

Каков предпочтительный метод добавления функциональности модуля в код ruby ​​библиотеки?

Обратите внимание на следующее:

module MyExceptions
    class SomethingBadHappenedTheLibarayDesignerDidntConsider < StandardError; end
end

Как добавить модуль MyExceptions в класс, который я не контролирую?


Обновление, в my_library_class_exceptions.rb Я сделал:

class LibraryClass
    include MyExceptions
end
module MyExceptions
    class SomethingBadHappenedTheLibarayDesignerDidntConsider < StandardError; end
end

Но консоль возвращает: NameError: uninitialized constant LibraryClass::MyExceptions

Ответы [ 3 ]

2 голосов
/ 20 октября 2011

В Ruby вы можете позже открыть определение любого класса и изменить его.

Ниже приведен надуманный пример переопределения деления для использования пользовательского исключения путем повторного открытия ранее созданного класса.

class Foo
  def divide(a, b)
    a/b
  end
end

foo = Foo.new()
foo.divide(1, 0)

module MyExceptions
  class MyDivisionError < StandardError; end
end

class Foo
  include MyExceptions
  alias old_divide divide
  def divide(a, b)
    old_divide(a, b)
  rescue ZeroDivisionError
    raise MyDivisionError
  end
end

foo.divide(1, 0)
1 голос
/ 20 октября 2011

Глядя на ваше обновление, простая причина, по которой оно не работает, заключается в следующем: вы используете MyExceptions до того, как оно будет определено. Исправлена ​​версия вашего файла - повторное открытие класса библиотеки:

require 'thelib'

module MyExceptions
    class SomethingBadHappenedTheLibarayDesignerDidntConsider < StandardError; end
end
LibraryClass.class_eval do
    include MyExceptions
end

Этот трюк с оценкой класса, возможно, является более безопасным способом повторного открытия класса, чем просто class LibraryClass снова: он предупредит вас, если вы пропустили имя класса.

Кстати: я действительно не понимаю, как вы планируете использовать MyException тогда ... это, вероятно, означало бы еще несколько обезьянок, исправляющих и / или упаковывающих части библиотеки.

ОБНОВЛЕНИЕ: вышеизложенное предполагает, что у вас есть thelib.rb в том же каталоге, по крайней мере со следующим содержимым:

class LibraryClass
end
0 голосов
/ 23 октября 2011

Я заработал, исправив несколько вещей и изменив несколько.

  1. Оказывается, LibraryClass на самом деле был не классом, а модулем. И я изменил:

    класс LibraryClass включить MyExceptions конец

в:

module LibraryClass
    module MyExceptions
        class SomethingBadHappenedTheLibarayDesignerDidntConsider < StandardError; end
    end
end
  1. Затем я переместил library_class.rb в lib\library_class_extensions.rb и убедился, что lib является частью пути автозагрузки.
  2. Затем в инициализаторе я позвонил require 'library_class_extensions'

Я думаю, что это лучший шаблон для поведения, которое я пытался выполнить, так как на самом деле это скорее код библиотечного типа, чем код app/model.

Я голосую за ответы, данные всеми за их героические усилия.

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