Ruby: kendini genişlet


113

Ruby'de temel fikrini anlıyorum extend. Bununla birlikte, bu kod segmentinde neler oluyor? Özellikle ne extendişe yarar? Örnek yöntemlerini sınıf yöntemlerine dönüştürmenin uygun bir yolu mu? Sınıf yöntemlerini baştan belirlemek yerine neden bu şekilde yaparsınız?

module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

  # what does the next line do?
  extend self
end

Yanıtlar:


115

Örnek yöntemlerini sınıf yöntemlerine dönüştürmenin uygun bir yoludur. Ancak daha verimli bir tekli olarak da kullanabilirsiniz .


2
Bu tür bir singleton neden daha verimli?
xuuso

5
Bağlantınız çürümüş dostum.
Ulysse BN

1
Bu yanıtı archive.org bağlantısıyla güncellendi
Mike Szyndel

1
Bu yanıt yetersizdir çünkü söz konusu anahtar kelimenin örnek yöntemlerini nasıl sınıf yöntemlerine dönüştürdüğünü açıklamaz. Aynı zamanda 'daha verimli bir tektonun' ne extend selfolduğunu veya bununla ne ilgisi olduğunu da açıklamıyor.
jayqui

29

Bir modülde self, modül sınıfının kendisidir. Yani mesela

puts self

Rake dönecek

extend self

temel olarak, Rake'de tanımlanan örnek yöntemlerini kullanılabilir hale getirir, böylece

Rake.run_tests

23

Benim için her zaman düşünmek yardımcı extendolarak includetekil sınıfına (ayrıca meta veya eigen sınıf olarak bilinir) içine.

Muhtemelen singleton sınıfında tanımlanan yöntemlerin temelde sınıf yöntemler olduğunu biliyorsunuzdur:

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

A.x #=> 'x'

Artık bunu bildiğimize göre, modüldeki yöntemler singleton sınıfının içinde extendolacak includeve böylece onları sınıf yöntemleri olarak gösterecek:

module A
  class << self
    include A

    def x
      puts 'x'
    end
  end

  def y
    puts 'y'
  end
end

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

15

Bağlantının bozulmasını önlemek için , Chris Wanstrath'ın user83510 tarafından bağlanan blog yazısı aşağıda yeniden yayınlanmıştır (onun izni ile). Yine de hiçbir şey bir orijinalin yerini alamaz, bu yüzden çalışmaya devam ettiği sürece onun bağlantısını kullanın.


→ singletons şarkı 18 Kasım 2008 Anlamadığım şeyler var. Örneğin David Bowie. Veya Güney Yarımküre. Ama hiçbir şey aklımı Ruby'nin Singleton'u kadar şaşırtamaz. Çünkü gerçekten, tamamen gereksiz.

İşte kodunuzla yapmanızı istedikleri şey:

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'

Ama bu çılgınlık. Güçle savaş.

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'

Herhangi bir neden olmasın? API daha özlüdür, kodun test edilmesi, alay edilmesi ve saplanması daha kolaydır ve ihtiyaç duyulduğunda uygun bir sınıfa dönüştürmek hala son derece basittir.

((telif hakkı on chris wanstrath olmalıdır))


Linkrot'tan kaçınmanın başka bir yolu, web.archive.org gibi bir yol geri dönüş makinesi kullanmaktır - web'deki sayfaların geçmişini tutar, yine de birçok linkrot durumunda oldukça yararlı buldum.
Kem Mason

3

extend selfmodül yöntemleri olarak tüm mevcut örnek yöntemlerini içerir. Bu demekle eşdeğerdir extend Rake. Ayrıca Rakesınıfın bir nesnesidir Module.

Eşdeğer davranışa ulaşmanın bir başka yolu da:

module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

end 

Rake.extend(Rake)

Bu, özel yöntemlerle kendi kendine yeten modülleri tanımlamak için kullanılabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.