2009-11-14 67 views
103

在Ruby中,我理解了extend的基本思想。但是,这段代码发生了什么?具体来说,extend做什么?这只是将实例方法变为类方法的简便方法吗?你为什么要这样做,而不是从一开始就指定类方法?Ruby:扩展自我

module Rake 
    include Test::Unit::Assertions 

    def run_tests # etc. 
    end 

    # what does the next line do? 
    extend self 
end 

回答

107

这是一个方便的将实例方法变为类方法的方法。但你也可以用它作为more efficient singleton

+2

为什么这种单身人士更有效率? – xuuso 2016-06-16 10:53:01

26

在模块中,self是模块类本身。因此,例如

puts self 

将返回耙 所以,

extend self 

基本上使得在提供给它的Rake定义的实例方法,所以你可以做

Rake.run_tests 
14

对于我来说,在单例类(也称为meta或eigen类)内部总是考虑extendinclude

你可能知道,单例类中定义的方法基本上是类方法:

module A 
    class << self 
    def x 
     puts 'x' 
    end 
    end 
end 

A.x #=> 'x' 

现在我们知道,extendinclude模块中的方法的单身类中,从而将它们公开为类方法:

module A 
    class << self 
    include A 

    def x 
     puts 'x' 
    end 
    end 

    def y 
    puts 'y' 
    end 
end 

A.x #=> 'x' 
A.y #=> 'y' 
3

extend self包括所有现有的实例方法作为模块方法。这相当于说extend RakeRake也是类Module的一个对象。

另一种方式来实现等效的行为将是:

module Rake 
    include Test::Unit::Assertions 

    def run_tests # etc. 
    end 

end 

Rake.extend(Rake) 

这可以用来定义自包含与私有方法的模块。

8

为了避免链接腐烂,由user83510链接的blog post of Chris Wanstrath将在下面转发(经他的许可)。 尽管如此,没有什么比原创的更好,所以只要继续工作,就使用他的链接。


→唱着单身 2008年11月18日 有东西,我只是不明白。比如大卫鲍伊。或南半球。但是像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更简洁,代码更易于测试,模拟和存根,并且在需要时将其转换为适当的类仍然非常简单。

((版权应该十十chris wanstrath))

+0

避免linkrot的另一种方式是使用类似于wayback机器的东西 - http://web.archive.org - 它保留了网页的历史记录,我发现它在很多情况下都是有用的。 – 2013-05-13 22:52:55