Ruby'de include ve Require arasındaki fark nedir?


Yanıtlar:


543

Ruby'de "içerme" ve "gerektirme" arasındaki fark nedir?

Cevap:

Dahil etme ve isteme yöntemleri çok farklı şeyler yapar.

Require yöntemi, diğer programlama dillerinde bulunanların çoğunu yapar: başka bir dosya çalıştırın. Ayrıca geçmişte nelere ihtiyaç duyduğunuzu da izler ve aynı dosyayı iki kez gerektirmez. Bu ek işlevsellik olmadan başka bir dosya çalıştırmak için load yöntemini kullanabilirsiniz.

İnclude yöntemi tüm yöntemleri başka bir modülden alır ve bunları geçerli modüle ekler. Bu, dil düzeyinde olduğu gibi dosya düzeyinde bir şeyin aksine, dil düzeyinde bir şeydir. Dahil etme yöntemi, sınıfları diğer modüllerle (genellikle karma olarak adlandırılır) "genişletmenin" birincil yoludur. Örneğin, sınıfınız "each" yöntemini tanımlıyorsa, Enumerable mixin modülünü dahil edebilirsiniz ve bu bir koleksiyon görevi görebilir. İçerme fiili diğer dillerde çok farklı kullanıldığı için bu kafa karıştırıcı olabilir.

Kaynak

Dolayısıyla, bir modülü genişletmek veya bir mix yapmak yerine kullanmak istiyorsanız, o zaman kullanmak istersiniz require.

Garip, Ruby'nin requireC'ler benzerdir includeRuby'nin iken, includeneredeyse C'ler benzemiyor include.


45
Aslında C'ler içerir, bir dosyayı gerektiği gibi yüklemez, bunun yerine #include satırını dosyanın içeriğiyle değiştirir. Eklenen dosyaların 'üstbilgi' olması gerekmez ve #include dosyanın başında olmak zorunda değildir, ancak sınıfta veya hatta yöntem tanımında olduğu gibi herhangi bir yerde olabilir. Bu, bir dosyadaki bazı yöntemleri yazarak ve bir sınıfın koduna ekleyerek C ++ 'da mixin yapabileceğiniz anlamına gelir, tam olarak ruby'de yaparsınız. Bu yüzden, C'lerde yaygın bir uygulama olmamasına rağmen, o kadar uzak değiller.
mb14

13
Bu cevap, örnekler ekleyerek yarar sağlayabilir.
Travis Bear

12
yapar gerektiren, cevap ne diyor aykırı: mb14 yaptığı yorum bu ima, ancak açıkça belirten ayılar değil "run" Dosya değil, yükler onu o içeren dosyanın parçası sanki. Bu anlamsal nitpick gibi görünebilir, ancak aslında oldukça önemli bir farktır.
Lonny Eachus

Harika bir açıklama. Son noktayı 'Tuhaf bir şekilde, Ruby'nin ihtiyacı C'nin içerisine benzerken, Ruby'nin dahil edilmesi neredeyse C'nin içerdiği gibi değil.
ArtSabintsev

1
@GregSchmit: includeRuby'de sadece miras. class C; include M endyapar Mve üst sınıfı Cve (eski) üst sınıf Cbir üst sınıfı M. C'nin includemiras yoluyla çalıştığını düşünmüyorum, bence basit metinsel / sözcüksel ikame.
Jörg W Mittag

100

Bir modül kullanıyorsanız, bu, tüm yöntemleri sınıfınıza getirdiğiniz anlamına gelir. Eğer extendmodüllü bir sınıfsanız, modülün yöntemlerini sınıf yöntemi olarak "getirdiğiniz" anlamına gelir . Eğer includemodüllü bir sınıfsanız bu, modülün yöntemlerini örnek yöntem olarak "getirdiğiniz" anlamına gelir .

EX:

 module A
   def say
     puts "this is module A"
   end
 end

 class B
   include A
 end

 class C
   extend A
 end

B.say => B: Sınıf için tanımsız yöntem 'say'

B.new.say => bu modül A

C.say => bu modül A

C.new.say => C: Sınıfı için tanımsız yöntem 'say'


23
Sanırım bu soruya cevap vermiyor, ama aradığım şey =)
Ciro Santilli :0 冠状 病 六四 事件 法轮功

2
Bu aslında requireve arasındaki farkların ne olduğu sorusuna cevap vermiyor include.

94

Metaprogramming Ruby kitabından,

require()Yöntem oldukça benzer load(), ancak farklı bir amaç için içindir. Kullanılacak load()kodu çalıştırmak için ve kullanmak require()kütüphaneleri ithal etmek.


73
Cevabınızdaki başka bir dil ile karşılaştırmamanız için oy verin :)
Stevo

Aşağıdakiler şu soru bağlamında cevap vermemek için oy kullandı: "Sınıfımdaki bir modülün yöntemlerini kullanmak istiyorsam?"
benc

57
  • Ruby requiredaha çok diğer dillerde "dahil" gibidir (C gibi). Ruby'ye başka bir dosyanın içeriğini getirmek istediğinizi söyler . Diğer dillerdeki benzer mekanizmalar şunlardır:

  • Ruby include, mixins için kullanılan nesne yönelimli bir miras mekanizmasıdır .

Burada iyi bir açıklama var :

Basit cevap, gereksinim ve içermenin esasen ilgisiz olmasıdır.

"gerektirir" acemi karışıklığa neden olabilir C içerir benzer. (Dikkate değer bir fark, ihtiyaç duyulduğunda gerekli dosyanın içindeki yerlilerin "buharlaşması" dır.)

Ruby dahil C dahil gibi bir şey değildir. İnclude deyimi bir modülü sınıfa "karıştırır". Bu bir var çoklu kalıtımın sınırlı formu . Dahil edilen bir modül, kelimenin tam anlamıyla onun dahil olduğu şey üzerinde bir "is-a" ilişkisine bahşeder.

Vurgu eklendi.


7

Hiç requirebir modül denediniz mi? Sonuçlar neydi? Sadece dene:

MyModule = Module.new
require MyModule # see what happens

Modüller gerekli değildir, sadece dahil!


Buradaki iddia doğru değil. Modüller gerekebilir. Ve yukarıdaki kodu çalıştıran herkes TypeError, kelime Moduleolarak değiştirilirse aynı sonucu ( ) aldıklarını görür Class.
pjd

7

Programlama Ruby 1.9 itibaren

Devam etmeden önce include ifadesi hakkında birkaç noktaya değineceğiz. İlk olarak, dosyalar ile ilgisi yoktur. C programcıları derleme sırasında bir dosyanın içeriğini diğerine eklemek için #include adlı bir önişlemci yönergesi kullanır. Ruby include deyimi bir modüle başvuruda bulunur. Bu modül ayrı bir dosyadaysa, include'u kullanmadan önce dosyayı sürüklemek için requir (ya da daha az kullanılan kuzeni, load) kullanmanız gerekir. İkincisi, Ruby içerme, modülün örnek yöntemlerini sınıfa kopyalamakla kalmaz. Bunun yerine, sınıftan dahil edilen modüle bir başvuru yapar. Birden fazla sınıf bu modülü içeriyorsa, hepsi aynı şeye işaret eder. Programınız çalışırken bile bir modül içindeki yöntemin tanımını değiştirirseniz,


3

Ekle Aşağıda gösterildiği gibi sınıfınıza bir modül eklediğinizde, modül içinde tanımlanan kodu alıp 'dahil ettiğiniz' sınıf içine eklediniz. 'Karıştırma' davranışına izin verir. Örneğin, modül içinde aynı koda ihtiyaç duyacak birden fazla sınıf varsa, çoğaltmayı önlemek için kodunuzu KURUTMAK için kullanılır.

Load (Yükle) Load (Yük) yöntemi, kütüphanenin yüklenip yüklenmediğini izlememesi dışında neredeyse bir yöntemdir. Bu nedenle, bir kitaplığı birden çok kez yüklemek mümkündür ve ayrıca yükleme yöntemini kullanırken kitaplık dosya adının “.rb” uzantısını belirtmeniz gerekir.

Zorunlu Zorunlu yöntem, bir kitaplığı yüklemenize olanak tanır ve birden çok kez yüklenmesini önler. Aynı kitaplığı ilk kez yüklemeye çalışırsanız, requir yöntemi 'false' değerini döndürür. Zorunlu yöntemin yalnızca, yüklediğiniz kitaplık ayrı bir dosyada tanımlanması durumunda kullanılmalıdır; bu genellikle durumdur.

Bunu http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/ tercih edebilirsiniz.


3

Aşağıda, gereksinim ve dahil etme arasında birkaç temel fark vardır:

gerektir:

  1. Require, dosyayı dosya sisteminden okur, ayrıştırır, belleğe kaydeder ve belirli bir yerde çalıştırır, yani komut dosyası çalışırken herhangi bir şeyi değiştirirseniz bu değişiklik yansıtmayacaktır.
  2. Modül adına değil dosya adına ihtiyacımız var.
  3. Genellikle kütüphaneler ve uzantılar için kullanılır.

Dahil etmek:

  1. Sınıfınıza bir modül eklediğinizde, modülünüzde tanımlanan kodu alıp sınıfınıza eklediğiniz gibi davranır.
  2. Dosya adını değil modül adını ekliyoruz.
  3. Genellikle kodu kurutmak ve koddaki çoğaltmayı kaldırmak için kullanılır.

2
require(name)

Bolean true / false döndürecek

Gereksinim için parametre olarak iletilen ad, ruby, yükleme yolunuzda bu ada sahip kaynak dosyayı bulmaya çalışır. Aynı kitaplığı ilk kez yüklemeye çalışırsanız, requir yöntemi 'false' değerini döndürür. Zorunlu yöntemin yalnızca yüklediğiniz kitaplık ayrı bir dosyada tanımlanmış olması durumunda kullanılması gerekir. Böylece bu kütüphanenin önceden yüklenmiş olup olmadığını takip eder.

include module_name

İki farklı sınıfta olması gereken bazı yöntemleriniz varsa varsayalım. O zaman onları her iki sınıfta da yazmak zorunda değilsiniz. Bunun yerine bunu modülde tanımlayın. Ve sonra bu modülü diğer sınıflara dahil edin. Sadece KURU prensibini sağlamak için Ruby tarafından sağlanır. Çoğaltmayı önlemek için kodunuzu KURUTMAK için kullanılır


2

Dahil etmek

Ne zaman sana includesen modülü içinde tanımlanan kod aldı ve bunu 'include' sınıfına, içinde bunu takılıysa gibi sınıfa bir modül, bu kadar. 'Karıştırma' davranışına izin verir. Örneğin, modül içinde aynı koda ihtiyaç duyacak birden fazla sınıf varsa, çoğaltmayı önlemek için kodunuzu KURUTMAK için kullanılır.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  include Log 
  # ... 
end

tc = TestClass.new.class_type # -> success
tc = TestClass.class_type # -> error

gerektir

Zorunlu yöntem, bir kitaplığı yüklemenize olanak tanır ve birden çok kez yüklenmesini önler. Aynı kitaplığı ilk kez yüklemeye çalışırsanız, requir yöntemi 'false' değerini döndürür. Zorunlu yöntemin yalnızca, yüklediğiniz kitaplık ayrı bir dosyada tanımlanması durumunda kullanılmalıdır; bu genellikle durumdur.

Böylece bu kütüphanenin önceden yüklenmiş olup olmadığını takip eder. Ayrıca kitaplık dosya adının “.rb” uzantısını belirtmeniz gerekmez. Gereksinimin nasıl kullanılacağına dair bir örnek. Require yöntemini “.rb” dosyanızın en üstüne yerleştirin:

Yük

Bu yöntem kitaplığın yüklenip yüklenmediğini izlememesi dışında load yöntemi neredeyse Require yöntemine benzer. Bu nedenle, bir kitaplığı birden çok kez yüklemek mümkündür ve ayrıca yükleme yöntemini kullanırken kitaplık dosya adının “.rb” uzantısını belirtmeniz gerekir.

uzatmak

İçerme yerine uzatma yöntemini kullanırken, modülün yöntemlerini örnek yöntemler yerine sınıf yöntemleri olarak eklersiniz.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  extend Log 
  # ... 
end

tc = TestClass.class_type

2

'Yükle' - bir dosyanın içeriğini ekler. (Dosya her çağrıldığında dosyayı ayrıştır)

'Gerekli' - dosya ayrıştırılmış içerik ekler. (Dosya bir kez ayrıştırıldı ve bellekte saklandı)

'Ekle' - modülü sınıfa dahil eder ve modülün içindeki yöntemleri sınıfın örnek yöntemi olarak kullanabilir

'Genişlet' - modülü sınıfa dahil eder ve modül içindeki yöntemleri sınıf yöntemi olarak kullanabilir

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.