Выяснение, где методы определены в Ruby/Rails (в отличие от Java)
Я только начинаю работать с Ruby on Rails. Исходя из Java-мира, мне интересно, как разработчики Ruby/Rails выясняют, какие методы фактически определены.
Я использую просто щелчок по методу в Eclipse, чтобы найти, где это определено, даже в сторонних библиотеках (предположим, что у меня есть исходный код).
Конкретный пример: я пытаюсь выяснить, как камень Authlogic, по-видимому, меняет конструктор моего класса User, чтобы потребовать дополнительный параметр (называемый: password_confirmation), хотя класс User даже не наследует ничего, связанное с Authlogic.
Вероятно, я просто обозреваю что-то действительно очевидное здесь (или, может быть, я все еще не могу обернуть голову вокруг всего "соглашения над конфигурацией", -))
Ответы
Ответ 1
Pry драгоценный камень предназначен именно для такого рода исследовательских вариантов использования.
Pry - интерактивная оболочка, которая позволяет вам перемещаться по исходному коду программы, используя команды типа оболочки, такие как cd
и ls
.
Вы можете вытащить документацию по любому методу, с которым вы сталкиваетесь, и даже просмотреть исходный код, в том числе собственный C-код в некоторых случаях (с плагином pry-doc
). Вы даже можете перейти непосредственно к файлу/строке, где определенный метод определен с помощью команды edit-method
. Команды show-method
и show-doc
также отображают точное местоположение метода, в котором они действуют.
Смотрите railscast screencast для получения дополнительной информации.
Вот несколько примеров ниже:
pry(main)> show-doc OpenStruct#initialize
From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/ostruct.rb @ line 46:
Number of lines: 11
visibility: private
signature: initialize(hash=?)
Create a new OpenStruct object. The optional hash, if given, will
generate attributes and values. For example.
require 'ostruct'
hash = { "country" => "Australia", :population => 20_000_000 }
data = OpenStruct.new(hash)
p data # -> <OpenStruct country="Australia" population=20000000>
By default, the resulting OpenStruct object will have no attributes.
pry(main)>
Вы также можете найти исходный код с помощью команды show-method
:
pry(main)> show-method OpenStruct#initialize
From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/ostruct.rb @ line 46:
Number of lines: 9
def initialize(hash=nil)
@table = {}
if hash
for k,v in hash
@table[k.to_sym] = v
new_ostruct_member(k)
end
end
end
pry(main)>
Подробнее см. http://pry.github.com:)
Ответ 2
Немного сложно быстро найти местоположение метода для динамических языков, таких как Ruby.
Вы можете использовать object.methods
или object.instance_methods
для быстрого поиска методов.
Если вы используете Ruby 1.9, вы можете сделать что-то вроде этого:
object.method(:method_name).source_location
Для получения дополнительной информации о source_location - нажмите здесь
Ответ 3
Никто из тех, кто советует Pry gem, не упоминает метод под названием find-method
, который, вероятно, искал автор.
Вот пример:
pry(main)> find-method current_user
Devise::Controllers::Helpers
Devise::Controllers::Helpers#current_user
WebsocketRails::ConnectionAdapters::Base
WebsocketRails::ConnectionAdapters::Base#current_user_responds_to?
Затем вы можете просмотреть код метода, следуя советам @banister.
Ответ 4
Вы можете использовать что-то вроде pry. Смотрите также railscast.
Ответ 5
Существует несколько способов изменить существующий класс. Например. если вы хотите изменить класс String write:
class String
def my_custom_method
puts "hello!"
end
end
Но есть и другие варианты, такие как смешивание в модулях или добавление/изменение методов с помощью метапрограммирования.
Во всяком случае, с некоторым объектом вы всегда можете:
puts obj.methods.inspect
Либо сделайте это в своем коде, либо используйте отладчик.
Другой вариант - прочитать код. В частности, вы должны прочитать тесты единиц драгоценных камней (./spec,...). Существует довольно много авторов, заявляющих, что модульные тесты делают документацию устаревшей.
Ответ 6
В Ruby вы также можете добавить методы класса и экземпляра в заданный класс с помощью mixins.
По существу, если у вас есть модуль, вы можете добавить его методы в данный класс, используя методы класса include и expand. Краткий пример того, как эти работы являются следующими
Module A
def foo
"foo"
end
end
Module B
def bar
"bar"
end
end
Class YourClass
include A
extend B
end
p YourClass.new.foo # gives "foo" because the foo method is added as instance method
p YourClass.bar # gives "baz" because the bar method is added as class method
Поскольку Ruby является динамическим языком, эти утверждения могут использоваться повсеместно. Поэтому, чтобы прийти к вашему вопросу, нет необходимости расширять класс authlogic, чтобы получить его методы. Многие плагины используют эту инструкцию при загрузке
ActiveRecord::Base.send :include, ModuleName
Таким образом они сообщают каждому объекту AR включить некоторый модуль, определенный модулем, и вы получите все методы в объектах AR.
Другой метод, используемый многими плагинами acts_as
, заключается в том, чтобы включать их модули только тогда, когда вызов acts_as
используется в базовом классе.
Другие полезные ссылки