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


302

Ruby'de require_relativeve requireRuby arasındaki fark nedir ?


9
1.9.2'den önce, geçerli script dizini içerdiğinden, requir_relative'a gerek yoktu $:. Bkz. Stackoverflow.com/questions/2900370
Nakilon

1
requir_relative, dosyayı çağıran dosyaya göre özel olarak işaretlenmiş bir dosya gerektirir. gerektirir, $ LOAD_PATH dosyasına dahil edilmiş bir dosya gerektirir.
Donato

farklılıklar hakkında yararlı makale => medium.com/@ellishim/…
ahmed hamdy

Yanıtlar:


298

Sadece dokümanlara bakın :

require_relativeifadeyi requireiçeren dosyaya göre bir dosya yüklemenize izin vererek yerleşik yöntemi tamamlar require_relative.

Örneğin, "test" dizininde birim test sınıfları ve test "test / data" dizini altında veriler varsa, bir test durumunda bu gibi bir çizgi kullanabilirsiniz:

require_relative "data/customer_data_1"

28
Arasında bir fark var mı require './file.rb've require_relative 'file.rb'?
Ciro Santilli 法轮功 冠状 病 郝海东 事件 法轮功

69
@CiroSantilli Evet. require_relative" ifadeyi içeren dosyaya görerequire_relative bir dosya yüklemenize" olanak tanır . İle require, ./geçerli çalışma dizininize göre olan bir yolu gösterir.
Ajedi32

16
Ben require strher zaman $ LOAD_PATH dizinleri her zaman arama not etmek daha önemli olduğunu düşünüyorum . require_relativeYüklemeniz gereken dosya, yüklemeyi gerektiren dosyaya göre bir yerde olduğunda kullanmalısınız . Rezerv require"dış" bağımlılıkları için.
30th

97

require_relative uygun bir alt kümesidir require

require_relative('path')

eşittir:

require(File.expand_path('path', File.dirname(__FILE__)))

eğer __FILE__tanımlanan, ya da yükseltir edilir LoadErroraksi.

Bu şu anlama gelir:

  • require_relative 'a've geçerli dosyaya ( ) require_relative './a'göre gerektirir .__FILE__

    Sonucun arayanın geçerli dizinine bağlı olmasını istemediğiniz için, kitaplığınızın içini gerektiğinde kullanmak istediğiniz budur.

  • eval('require_relative("a.rb")')yükseltmeler LoadErrorçünkü __FILE__içeride tanımlanmamıştır eval.

    Bu nedenle require_relativeedindiğiniz RSpec testlerinde kullanamazsınız eval.

Aşağıdaki işlemler sadece aşağıdakilerle mümkündür require:

  • require './a.rb'geçerli dizine göre gerektirir

  • require 'a.rb'gereken arama yolunu ( $LOAD_PATH) kullanır . Geçerli dizine veya yola göre dosyaları bulamaz.

    Bu mümkün değildir require_relativeçünkü dokümanlar yol aramanın yalnızca "dosya adı mutlak bir yola çözümlenmediğinde" (yani /ya ./da ya da ile başlar ../) her zaman böyle olduğu zaman gerçekleştiğini söylüyor File.expand_path.

Aşağıdaki işlem her ikisiyle de mümkündür, ancak requiredaha kısa ve daha verimli olduğu için kullanmak isteyeceksiniz :

  • require '/a.rb've require_relative '/a.rb'her ikisi de mutlak yol gerektirir.

Kaynağı okuma

Dokümanlar net olmadığında, kaynaklara göz atmanızı öneririm (dokümanlardaki kaynağı değiştir). Bazı durumlarda, neler olduğunu anlamaya yardımcı olur.

gerektirir:

VALUE rb_f_require(VALUE obj, VALUE fname) {
  return rb_require_safe(fname, rb_safe_level());
}

require_relative:

VALUE rb_f_require_relative(VALUE obj, VALUE fname) {
    VALUE base = rb_current_realfilepath();
    if (NIL_P(base)) {
        rb_loaderror("cannot infer basepath");
    }
    base = rb_file_dirname(base);
    return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}

Bu,

require_relative('path')

aynıdır:

require(File.expand_path('path', File.dirname(__FILE__)))

Çünkü:

rb_file_absolute_path   =~ File.expand_path
rb_file_dirname1        =~ File.dirname
rb_current_realfilepath =~ __FILE__

74

Ruby API'sından :

requir_relative, requir_relative deyimini içeren dosyaya ilişkin bir dosyayı yüklemenize izin vererek, builtin yöntemini tamamlar.

Bir dosya yüklemeyi gerektirdiğini kullandığınızda, genellikle sisteminizde düzgün şekilde yüklenmiş ve erişilebilir hale getirilmiş işlevselliğe erişirsiniz. Proje proje kodu içinde dosya yüklemek için iyi bir çözüm sunmaz. Bu, geliştirme aşamasında, test verilerine erişmek veya hatta bir proje içinde "kilitli" olan ve dışarıda kullanım için tasarlanmamış dosyalara erişmek için yararlı olabilir.

Örneğin, "test" dizininde birim test sınıfları ve test "test / data" dizini altında veriler varsa, bir test durumunda bu gibi bir çizgi kullanabilirsiniz:

require_relative "data/customer_data_1" 

Ne "test" ne de "test / veri" Ruby'nin kütüphane yolunda (ve iyi bir nedenle) bulunmadığından, normal bir gereksinim onları bulamaz. requir_relative bu sorun için iyi bir çözümdür.

Yüklediğiniz dosyanın uzantısını (.rb veya .so) ekleyebilir veya atlayabilirsiniz.

yol yanıt vermek zorundadır.

Belgeleri http://extensions.rubyforge.org/rdoc/classes/Kernel.html adresinde bulabilirsiniz.


50

özet

requireTakılı taşlar için kullanın

require_relativeYerel dosyalar için kullan

require$LOAD_PATHdosyaları bulmak için kullanır .
require_relativeifadesini kullanarak dosyanın geçerli konumunu kullanır


gerektirir

Require gem install [package], bu işlevsellik için sisteminizde bir yere bir paket kurmanıza (örn. ) Bağlıdır.

Kullanırken requiresiz yapabilirsiniz "kullanmak ./geçerli dizinde, örneğin bir dosya için" biçimini require "./my_file"ama bu bir ortak ya da tavsiye uygulama değildir ve kullanmak gerekir require_relativebunun yerine.

require_relative

Bu sadece 'requir_relative deyimi ile dosyanın konumuna göre' dosyasını dahil etmek anlamına gelir. Ben genellikle örneğin "yukarı" aksine bu dosyalar geçerli dizin ağacında "dahilinde" olmalıdır tavsiye yok kullanımını

require_relative '../../../filename'

(3 dizin seviyesine kadar) dosya sistemi içinde gereksiz ve kırılgan bağımlılıklar oluşturma eğilimindedir. Ancak bazı durumlarda zaten bir dizin ağacında 'derin' iseniz, o zaman "yukarı ve aşağı" başka bir dizin ağacı dalı gerekebilir. Daha basit olarak , bu deponun dışındaki dosyalar için requir_relative kullanmayın (bu noktada, 2018'in sonlarında fiili bir standart olan git'i kullandığınızı varsayalım).

Requir_relative deyimi ile dosyanınrequire_relative geçerli dizinini kullandığını unutmayın (bu nedenle, komutunu kullandığınız geçerli dizininiz olması gerekmez). Bu, yolu her zaman aynı şekilde gerektiren dosyaya göreli olacağından yolu "sabit" tutar .require_relative


27

En iyi cevaplar doğru, ancak derin teknik. Ruby'den daha yeni olanlar için:

  • require_relative büyük olasılıkla yazdığınız başka bir dosyadan kod getirmek için kullanılır.

örneğin, verileriniz varsa ~/my-project/data.rbve buna veri eklemek istiyorsanız ne olur ~/my-project/solution.rb? içinde solution.rbsize eklersiniz require_relative 'data'.

bu dosyaların aynı dizinde olması gerekmediğine dikkat etmek önemlidir. require_relative '../../folder1/folder2/data'de geçerlidir.

  • require büyük olasılıkla başka birinin yazdığı bir kütüphaneden kod getirmek için kullanılacaktır.

örneğin, active_supportkitaplıkta sağlanan yardımcı işlevlerden birini kullanmak isterseniz ne olur ? gem'i gem install activesupportve sonra dosyaya yüklemeniz gerekir require 'active_support'.

require 'active_support/all'
"FooBar".underscore

Farklı dedi ki ...

  • require_relative onu çağıran dosyaya göre özel olarak işaretlenmiş bir dosya gerektirir.

  • require, içinde bulunan bir dosya gerektirir $LOAD_PATH.


3
Bu cevabı nasıl oylayabilirim ve onu en üste nasıl getirebilirim, bu yüzden bu soru sayfasını ziyaret eden herkes beynini kırmadan hemen net ve anlaşılır bir cevap alacak mı?
TiredOfProgramming

16

Az önce RSpec'in kodunun require_relativeO (1) sabiti ve requireO (N) doğrusal olması üzerine bazı yorumları olduğunu gördüm . Yani muhtemelen fark, require_relativetercih edilenin olmasıdır require.


1
İlginç. Buraya hız karşılaştırması hakkında bilgi almak için indim. Benim düşüncem require_relativedaha hızlıydı, çünkü yükleyici dosyayı aramak için yükleme yolundan geçmek zorunda değil. Esasen require_relativedoğrudan bir bağlantı sağlar.
Clint Pachl

Hakkında Erken Tartışma require_relative hız ve RSpec değişmek .
Clint Pachl

1

Windows'u kullanırken require './1.rb'komut dosyası yerel veya eşlenmiş bir ağ sürücüsünden çalıştırılabiliyor ancak bir UNC \\servername\sharename\folderyolundan çalıştırıldığında kullanabileceğinizi eklemek istiyorumrequire_relative './1.rb' .

Başka nedenlerle kullanılacak tartışmada karışmam.


Ben yüklemek nasıl bilmek istedim require_relativeşuna bir fikir atmak misiniz dosyayı stackoverflow.com/questions/43487784/...
Emjey
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.