Ruby Methods: как вернуть строку использования при недостаточном количестве аргументов - PullRequest
3 голосов
/ 14 апреля 2010

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

ArgumentError: wrong number of arguments (0 for 9)

Поэтому я предпочитаю возвращать строку с понятными для человека аргументами, например, используя «put» или просто возврат строки. Теперь я видел ключевое слово rescue внутри кода begin-end, но мне интересно, как я мог перехватить ArgumentError при вызове метода initialize.

Спасибо за ваши ответы, отзывы и комментарии!

1 Ответ

4 голосов
/ 14 апреля 2010

Можно подключиться к созданию объекта, переопределив метод Class#new, например,

class Class
  # alias the original 'new' method before overriding it
  alias_method :old_new, :new
  def new(*args)
    return old_new(*args)
    rescue ArgumentError => ae          
      if respond_to?(:usage)
        raise ArgumentError.new(usage)
      else 
        raise ae
      end
  end
end

Этот переопределенный метод вызывает обычный метод new, но перехватывает ArgumentError и, если класс объектасоздаваемый метод usage затем вызывает ArgumentError с сообщением об использовании, в противном случае будет восстановлен исходный ArgumentError.

Вот пример его в действии.Определите класс Person:

class Person
  def initialize(name, age)
  end

  def self.usage
    "Person.new should be called with 2 arguments: name and age"
  end
end

, а затем попытайтесь создать его без обязательных аргументов:

irb(main):019:0> p = Person.new
ArgumentError: Person.new should be called with 2 arguments: name and age
    from (irb):8:in `new'
    from (irb):22

Примечание : это не идеально.Основная проблема заключается в том, что возможно, что ArgumentError, который мы перехватываем, был вызван чем-то иным, чем неправильным количеством аргументов, передаваемых initialize, что могло бы привести к вводящему в заблуждение сообщению.Однако в большинстве случаев он должен делать то, что вы хотите.

...