Answers:
在模块中,self是模块类本身。所以举个例子
puts self
将返回Rake,
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'
为了避免链接腐烂,由user83510链接的Chris Wanstrath的博客文章重新张贴在下面(未经他的许可)。不过,没有什么能比原始作品更好,因此只要可以继续使用,就使用他的链接。
→singin'singletons 2008年11月18日,有些东西我只是听不懂。例如,大卫·鲍伊(David Bowie)。或南半球。但是,没有什么比Ruby的Singleton令我更困惑。因为真的,这完全没有必要。
这是他们希望您对代码进行的处理:
require 'net/http'
# first you setup your singleton
class Cheat
include Singleton
def initialize
@host = 'http://cheat.errtheblog.com/'
@http = Net::HTTP.start(URI.parse(@host).host)
end
def sheet(name)
@http.get("/s/#{name}").body
end
end
# then you use it
Cheat.instance.sheet 'migrations'
Cheat.instance.sheet 'yahoo_ceo'
但这太疯狂了。与权威对抗。
require 'net/http'
# here's 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'
为什么不呢?API更简洁,代码更易于测试,模拟和存根,如果需要,将其转换为适当的类仍然很简单。
((版权应为十克里斯·万斯特拉斯))
extend self
包括所有现有实例方法作为模块方法。这相当于说extend Rake
。也是Rake
类的对象Module
。
实现等效行为的另一种方法是:
module Rake
include Test::Unit::Assertions
def run_tests # etc.
end
end
Rake.extend(Rake)
这可用于使用私有方法定义自包含模块。