Ответ 1
Это удобный способ сделать методы экземпляра в методах класса. Но вы также можете использовать его как более эффективный синглтон.
В Ruby я понимаю основную идею extend
. Однако что происходит в этом сегменте кода? В частности, что делает extend
? Это просто удобный способ сделать методы экземпляра в методах класса? Зачем вам это делать, а не определять методы класса с самого начала?
module Rake
include Test::Unit::Assertions
def run_tests # etc.
end
# what does the next line do?
extend self
end
Это удобный способ сделать методы экземпляра в методах класса. Но вы также можете использовать его как более эффективный синглтон.
В модуле self является самим модулем. Так, например,
puts self
вернется Рейк поэтому
extend self
в основном делает доступными для него методы экземпляров, определенные в Rake, поэтому вы можете сделать
Rake.run_tests
Для меня всегда полезно думать о extend
как include
внутри одноэлементного класса (также известного как мета или собственный класс).
Вероятно, вы знаете, что методы, определенные внутри класса singleton, являются в основном методами класса:
module A
class << self
def x
puts 'x'
end
end
end
A.x #=> 'x'
Теперь, когда мы знаем, что extend
будет include
методов в модуле внутри одноэлементного класса и, таким образом, подвергает их методам класса:
module A
class << self
include A
def x
puts 'x'
end
end
def y
puts 'y'
end
end
A.x #=> 'x'
A.y #=> 'y'
Чтобы избежать гниения ссылок, сообщение
Но это безумие. Борьба с силой.
require 'net/http'
# here how we roll
module Cheat
extend self
def host
@host ||= 'http://cheat.errtheblog.com/'
end
def http
@http ||= Net::HTTP.start(URI.parse(host).host)
end
def sheet(name)
http.get("/s/#{name}").body
end
end
# then you use it
Cheat.sheet 'migrations'
Cheat.sheet 'singletons'
((авторское право должно быть десять chris wanstrath))
extend self
включает все существующие методы экземпляра в качестве модульных методов. Это эквивалентно высказыванию extend Rake
. Также Rake
является объектом класса Module
.
Другим способом достижения эквивалентного поведения будет:
module Rake
include Test::Unit::Assertions
def run_tests # etc.
end
end
Rake.extend(Rake)
Это можно использовать для определения автономных модулей с частными методами.