Как проверить, какой класс реализует указанный метод в Ruby? - PullRequest
3 голосов
/ 25 января 2012

В одном из примеров Ruby я вижу следующий код:

require 'net/http'
req = Net::HTTP::Get.new( "http://localhost:8080/" )
req.basic_auth( "user", "password" )

Какой самый простой способ узнать, какой класс Ruby действительно реализует этот метод basic_auth или он генерируется динамически?Я проверил public_methods Net::HTTP::Get, и он определенно не там.Но как проверить, какой класс на самом деле его реализует?

Ответы [ 2 ]

8 голосов
/ 25 января 2012

Обычно вы используете метод Kernel#method для получения объекта Method для рассматриваемого метода, а затем вы используете метод Method#owner для запроса объекта Method, где он был определен.

Итак,

req.method(:basic_auth).owner
# => Net::HTTPHeader

должен ответить на ваш вопрос.

За исключением, в данном конкретном случае, это не сработает, поскольку req является Net::HTTP::Get object и Net::HTTP::Get переопределяют метод method для обозначения чего-то совершенно другого.В частности, он не принимает аргумент, поэтому приведенный выше код фактически вызовет ArgumentError.

Однако, поскольку Net::HTTP::Get наследуется от Object, а Object смешивается в Kernel, допустимо привязывать метод Kernel#method к экземпляру Net::HTTP::Get:

Kernel.instance_method(:method).bind(req).(:basic_auth).owner
# => Net::HTTPHeader

Итак, ваш ответ: метод определен в Net::HTTPHeader.

0 голосов
/ 25 января 2012

Я определил метод Object с именем which (чтобы напомнить команду * nix which), чтобы узнать, где определен метод.

Вот код:

class Object
  def which method
    self.class.ancestors.find { |a| a.instance_methods(false).include? method.to_s }
  end
end

Вот как я использую:

puts req.which :basic_auth    #=> Net::HTTPHeader
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...