it-swarm-ja.tech

Ruby:自己拡張

Rubyでは、extendの基本的な考え方を理解しています。しかし、このコードセグメントでは何が起きているのでしょうか?具体的には、extendは何をしますか?インスタンスメソッドをクラスメソッドにする便利な方法ですか?最初からクラスメソッドを指定するのではなく、なぜこのようにしたのですか?

module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

  # what does the next line do?
  extend self
end
113
Peter

インスタンスメソッドをクラスメソッドにする便利な方法です。しかし、 より効率的なシングルトン として使用することもできます。

114
cldwalker

モジュールでは、selfはモジュールクラスそのものです。例えば

puts self

rakeを返すので、

extend self

基本的に、Rakeで定義されたインスタンスメソッドを利用できるようにします。

Rake.run_tests
29
ennuikiller

私にとっては、シングルトンクラス(メタクラスまたは固有クラスとも呼ばれます)内でextendincludeと考えるのが常に役立ちます。

シングルトンクラス内で定義されたメソッドは、基本的にクラスメソッドであることをご存知でしょう。

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'
22
fphilipe

リンクの腐敗を防ぐため、user83510によってリンクされた Chris Wanstrathのブログ投稿 が(彼の許可を得て)以下に再投稿されます。それでも、オリジナルに勝るものはありませんので、それが機能し続ける限り、彼のリンクを使用してください。


→singing 'singletons 2008年11月18日私には理解できないことがあります。例えば、デヴィッド・ボウイ。または南半球。しかし、Rubyのシングルトンほど私の心を揺さぶるものはありません。本当に、それはまったく不要だからです。

彼らはあなたのコードで何をしたいのですか?

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はより簡潔で、コードのテスト、モック、およびスタブの作成が簡単であり、必要に応じて適切なクラスに変換するのは簡単です。

((著作権は10のクリス・ワンストラスのはずです))

14
forforf

extend selfには、既存のすべてのインスタンスメソッドがモジュールメソッドとして含まれています。これは、extend Rake。また、RakeModuleクラスのオブジェクトです。

同等の動作を実現する別の方法は次のとおりです。

module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

end 

Rake.extend(Rake)

これは、プライベートメソッドで自己完結型モジュールを定義するために使用できます。

3
Sulabh Jain