Ruby: memperpanjang diri

113

Di Ruby, saya memahami ide dasar extend. Namun, apa yang terjadi di segmen kode ini? Secara khusus, apa yang extenddilakukannya? Apakah ini hanya cara mudah untuk membuat metode instance menjadi metode kelas? Mengapa Anda melakukannya dengan cara ini daripada menentukan metode kelas dari awal?

module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

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

Jawaban:

115

Ini adalah cara yang mudah untuk membuat metode instance menjadi metode kelas. Tapi Anda juga bisa menggunakannya sebagai singleton yang lebih efisien .

cldwalker
sumber
2
Mengapa singleton semacam itu lebih efisien?
xuuso
5
Tautan Anda telah membusuk, teman saya.
Ulysse BN
1
Memperbarui jawaban ini dengan tautan ke archive.org
Mike Szyndel
1
Jawaban ini kurang memadai karena tidak menjelaskan bagaimana kata kunci yang dimaksud membuat metode instance menjadi metode kelas. Itu juga tidak menjelaskan apa itu 'singleton yang lebih efisien', atau apa extend selfhubungannya dengan itu.
jayqui
29

Dalam sebuah modul, self adalah kelas modul itu sendiri. Jadi contohnya

puts self

akan mengembalikan Rake jadi,

extend self

pada dasarnya membuat metode instance yang ditentukan dalam Rake tersedia untuknya, jadi Anda bisa melakukannya

Rake.run_tests
ennuikiller
sumber
23

Bagi saya itu selalu membantu untuk memikirkan extendsebagai includedi dalam kelas tunggal (juga dikenal sebagai kelas meta atau eigen).

Anda mungkin tahu bahwa metode yang ditentukan di dalam kelas tunggal pada dasarnya adalah metode kelas:

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

A.x #=> 'x'

Sekarang setelah kita mengetahuinya, extendakankah includemetode dalam modul di dalam kelas singleton dan dengan demikian mengeksposnya sebagai metode kelas:

module A
  class << self
    include A

    def x
      puts 'x'
    end
  end

  def y
    puts 'y'
  end
end

A.x #=> 'x'
A.y #=> 'y'
fphilipe
sumber
15

Untuk menghindari pembusukan link, postingan blog Chris Wanstrath yang ditautkan oleh user83510 di-posting ulang di bawah ini (dengan izinnya). Tetap saja, tidak ada yang mengalahkan yang asli, jadi gunakan tautannya selama itu terus berfungsi.


→ bernyanyi lajang 18 November 2008 Ada hal-hal yang tidak saya mengerti. David Bowie, misalnya. Atau Belahan Bumi Selatan. Tapi tidak ada yang cukup mengejutkan saya seperti Ruby Singleton. Karena sungguh, itu sama sekali tidak perlu.

Inilah yang mereka ingin Anda lakukan dengan kode Anda:

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'

Tapi itu gila. Lawan kekuatan.

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'

Ada kenapa tidak? API lebih ringkas, kodenya lebih mudah untuk diuji, dibuat-buat, dan bertopik, dan masih sangat mudah untuk diubah menjadi kelas yang tepat jika diperlukan.

((hak cipta seharusnya sepuluh chris wanstrath))

forforf
sumber
Cara lain untuk menghindari linkrot adalah dengan menggunakan sesuatu seperti mesin wayback - web.archive.org - ini menyimpan riwayat halaman di seluruh web, saya merasa cukup membantu dalam banyak kasus linkrot.
Kem Mason
3

extend selfmenyertakan semua metode instance yang ada sebagai metode modul. Ini sama dengan mengatakan extend Rake. Juga Rakemerupakan objek kelas Module.

Cara lain untuk mencapai perilaku yang setara adalah:

module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

end 

Rake.extend(Rake)

Ini dapat digunakan untuk mendefinisikan modul mandiri dengan metode privat.

Sulabh Jain
sumber