#ruby-on-rails #ruby
#ruby-on-rails #ruby
Вопрос:
Кажется, что эти две части кодов выполняют одну и ту же работу, но я хотел бы понять, почему я предпочел бы использовать тот или иной
Первый пример:
module MyModule
extend self
def first_method
end
def second_method
end
end
Второй пример:
module MyModule
def self.first_method
end
def self.second_method
end
end
Комментарии:
1. Это чисто Ruby вопрос, поэтому у него не должно быть тега Rails. Одним из следствий является то, что читатели, которые отфильтровали вопросы Rails (но не вопросы Ruby), не увидят ваш вопрос.
Ответ №1:
Ваш первый пример определяет два метода экземпляра и делает их также доступными как методы класса (или модуля) через extend
:
module MyModule
def first_method; end
def second_method; end
end
MyModule.instance_methods #=> [:second_method, :first_method]
MyModule.methods - Module.methods #=> []
MyModule.extend MyModule
MyModule.instance_methods #=> [:second_method, :first_method]
MyModule.methods - Module.methods #=> [:second_method, :first_method]
В то время как ваш второй пример просто определяет два метода класса (или модуля) и не содержит методов экземпляра:
module MyModule
def self.first_method; end
def self.second_method; end
end
MyModule.instance_methods #=> []
MyModule.methods - Module.methods #=> [:second_method, :first_method]
Первый вариант может быть полезен, когда вы хотите предоставить некоторые служебные функции, которые можно вызывать как:
MyModule.first_method
или быть включенным в другие модули / классы:
class Foo
include MyModule
def another_method
first_method # <- no explicit receiver needed
end
end
Ruby также предоставляет вспомогательный метод module_function
для определения методов таким образом:
module MyModule
def first_method
end
module_function :first_method
end
Он добавляет метод в качестве методов класса и делает метод экземпляра частным. Вот как работают методы в Kernel
.
Комментарии:
1. спасибо, что нашли время и за ваш наглядный пример 🙂
2. Поскольку вы зашли так далеко, подумайте также о том, чтобы упомянуть
self.included(klass)
идиому для включения одних методов и расширения других.