В ruby вы можете добавить или изменить любой метод в любом объекте. Вы даже можете добавить новый метод к экземпляру строки, например:
x = "xyzzy"
x.name # => NoMethodError: undefined method `name' for "xyzzy":String
x.instance_eval do
class << self
define_method(:name) {"I got a name"}
end
end
x.class # => String
x.name # => "I got a name"
y = "other"
y.class # => String
y.name # => NoMethodError: undefined method `name' for "other":String
Этот метод build
мог быть «добавлен» к экземпляру Array, возвращенному средством доступа comments
, созданным макросом has_many
. (Как указал Гарет, Rails немного усложнил ситуацию, и ассоциации не работают таким образом. Однако расширение объектов может быть более «чистым» способом по сравнению с работой в качестве прозрачного прокси. Рассмотрим мой пример как ruby , не рельсы)
Что касается второй части вашего вопроса, вы можете узнать методы данного объекта, обратившись к его функции methods
. Он возвращает имена всех (открытых) методов, определенных для этого объекта. (Если вам нужны частные, см. Функцию private_methods
.)
В моем примере x.methods
будет включать также недавно определенный метод "name", но y.methods
не будет.
В ruby есть и другие функции, с помощью которых вы можете исследовать объекты. Вы можете найти их в документации Ruby API . API может иметь некоторые (обычно незначительные) изменения в различных версиях ruby. См. Документацию по используемой версии.
Если вы хотите изучить код какого-либо метода, то это может быть небольшой проблемой, поскольку «исполняемый код» функции может быть создан разными способами: это может быть копия (псевдоним) другой функции, она может быть создана динамически с помощью функции eval
и т. Д.
Зная название метода, вы можете «найти» исходный код, который у вас есть, и, возможно, нужный метод не был создан динамически.
Я вижу, что проект ParseTree все еще жив. Может быть, вы найдете это полезным, если вы действительно хотите знать код функции, к которой у вас нет источников.