Ruby:扩展自我

Pet*_*ter 113 ruby

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

module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

  # what does the next line do?
  extend self
end
Run Code Online (Sandbox Code Playgroud)

cld*_*ker 114

这是将实例方法转换为类方法的便捷方法.但您也可以将其用作更高效的单身人士.

  • 你的链接烂了我的朋友. (5认同)
  • 这个答案是不充分的,因为它没有解释所讨论的关键字“如何”将实例方法变成类方法。它也没有解释什么是“更高效的单例”,或者“扩展自我”与此有何关系。 (4认同)
  • 为什么这种单身人士更有效率? (2认同)
  • 使用指向 archive.org 的链接更新了此答案 (2认同)

enn*_*ler 29

在模块中,self是模块类本身.所以举个例子

puts self
Run Code Online (Sandbox Code Playgroud)

将返回Rake,

extend self
Run Code Online (Sandbox Code Playgroud)

基本上使得Rake中定义的实例方法可用,所以你可以这样做

Rake.run_tests
Run Code Online (Sandbox Code Playgroud)


fph*_*ipe 22

对我而言,将单元类(也称为元或本类)extend视为include内部总是有帮助的.

您可能知道在singleton类中定义的方法基本上是类方法:

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

A.x #=> 'x'
Run Code Online (Sandbox Code Playgroud)

现在我们知道,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'
Run Code Online (Sandbox Code Playgroud)


for*_*orf 14

为了避免链接腐烂,用户83510链接的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'
Run Code Online (Sandbox Code Playgroud)

但那太疯狂了.与权威对抗.

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'
Run Code Online (Sandbox Code Playgroud)

为什么不呢?API更简洁,代码更容易测试,模拟和存根,并且在需要时转换为适当的类仍然很简单.

((版权应该十克里斯万斯特))