Apa perbedaan antara require_relative
dan require
di Ruby?
Apa perbedaan antara require_relative
dan require
di Ruby?
Jawaban:
Lihat saja dokumen :
require_relative
melengkapi metode bawaanrequire
dengan memungkinkan Anda untuk memuat file yang relatif terhadap file yang berisirequire_relative
pernyataan.Misalnya, jika Anda memiliki kelas uji unit dalam direktori "test", dan data untuk mereka di bawah direktori test "test / data", maka Anda dapat menggunakan baris seperti ini dalam case test:
require_relative "data/customer_data_1"
require './file.rb'
dan require_relative 'file.rb'
?
require_relative
memungkinkan Anda untuk "memuat file yang relatif terhadap file yang berisi require_relative
pernyataan ". Dengan require
, ./
menunjukkan jalur yang relatif terhadap direktori kerja Anda saat ini.
require str
akan selalu mencari melalui direktori di $ LOAD_PATH. Anda harus menggunakan require_relative
ketika file yang Anda perlu memuat ada di suatu tempat relatif terhadap file yang memanggil untuk memuat. Cadangan require
untuk dependensi "eksternal".
require_relative
adalah bagian nyaman dari require
require_relative('path')
sama dengan:
require(File.expand_path('path', File.dirname(__FILE__)))
jika __FILE__
didefinisikan, atau memunculkan LoadError
sebaliknya.
Ini menyiratkan bahwa:
require_relative 'a'
dan require_relative './a'
membutuhkan relatif ke file saat ini ( __FILE__
).
Ini adalah apa yang ingin Anda gunakan ketika memerlukan di dalam perpustakaan Anda, karena Anda tidak ingin hasilnya bergantung pada direktori pemanggil saat ini.
eval('require_relative("a.rb")')
menimbulkan LoadError
karena __FILE__
tidak didefinisikan di dalam eval
.
Inilah sebabnya mengapa Anda tidak dapat menggunakan require_relative
dalam tes RSpec, yang menjadi eval
ed.
Operasi berikut hanya dapat dilakukan dengan require
:
require './a.rb'
membutuhkan relatif ke direktori saat ini
require 'a.rb'
menggunakan jalur pencarian ( $LOAD_PATH
) untuk meminta. Itu tidak menemukan file relatif terhadap direktori atau jalur saat ini.
Ini tidak dimungkinkan dengan require_relative
karena dokumen mengatakan bahwa pencarian jalur hanya terjadi ketika "nama file tidak menyelesaikan ke jalur absolut" (yaitu dimulai dengan /
atau ./
atau ../
), yang selalu menjadi kasus untuk File.expand_path
.
Operasi berikut ini dimungkinkan dengan keduanya, tetapi Anda ingin menggunakannya require
karena lebih pendek dan lebih efisien:
require '/a.rb'
dan require_relative '/a.rb'
keduanya membutuhkan jalur absolut.Membaca sumbernya
Ketika dokumen tidak jelas, saya sarankan agar Anda melihat sumber (beralih sumber di dokumen). Dalam beberapa kasus, membantu memahami apa yang sedang terjadi.
memerlukan:
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());
}
Ini memungkinkan kita untuk menyimpulkan itu
require_relative('path')
sama dengan:
require(File.expand_path('path', File.dirname(__FILE__)))
karena:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
Dari Ruby API :
require_relative melengkapi metode builtin mengharuskan dengan memungkinkan Anda untuk memuat file yang relatif terhadap file yang berisi pernyataan require_relative.
Ketika Anda menggunakan harus memuat file, Anda biasanya mengakses fungsionalitas yang telah diinstal dengan benar, dan dapat diakses, di sistem Anda. mengharuskan tidak menawarkan solusi yang baik untuk memuat file dalam kode proyek. Ini mungkin berguna selama fase pengembangan, untuk mengakses data uji, atau bahkan untuk mengakses file yang "dikunci" di dalam proyek, tidak dimaksudkan untuk penggunaan luar.
Misalnya, jika Anda memiliki kelas uji unit dalam direktori "test", dan data untuk mereka di bawah direktori test "test / data", maka Anda dapat menggunakan baris seperti ini dalam case test:
require_relative "data/customer_data_1"
Karena baik "tes" atau "tes / data" kemungkinan berada di jalur perpustakaan Ruby (dan untuk alasan yang baik), kebutuhan normal tidak akan menemukannya. require_relative adalah solusi yang bagus untuk masalah khusus ini.
Anda dapat menyertakan atau menghilangkan ekstensi (.rb atau .so) dari file yang Anda muat.
path harus menanggapi to_str.
Anda dapat menemukan dokumentasi di http://extensions.rubyforge.org/rdoc/classes/Kernel.html
require
untuk permata yang terpasangrequire_relative
untuk file lokalrequire
menggunakan Anda $LOAD_PATH
untuk menemukan file.
require_relative
menggunakan lokasi file saat ini menggunakan pernyataan
Perlu bergantung pada Anda telah menginstal (misalnya gem install [package]
) paket di suatu tempat di sistem Anda untuk fungsionalitas itu.
Saat menggunakan require
Anda dapat menggunakan ./
format " " untuk file di direktori saat ini, mis. require "./my_file"
Tapi itu bukan praktik yang umum atau disarankan dan Anda harus menggunakannya require_relative
.
Ini berarti memasukkan file 'relatif ke lokasi file dengan pernyataan require_relative'. Saya biasanya merekomendasikan bahwa file harus "di dalam" pohon direktori saat ini sebagai lawan dari "naik", misalnya jangan gunakan
require_relative '../../../filename'
(naik 3 level direktori) dalam sistem file karena itu cenderung membuat dependensi yang tidak perlu dan rapuh. Namun dalam beberapa kasus jika Anda sudah 'dalam' di dalam pohon direktori maka "naik turun" cabang pohon direktori lain mungkin diperlukan. Mungkin lebih sederhana, jangan gunakan require_relative untuk file di luar repositori ini (dengan asumsi Anda menggunakan git yang sebagian besar merupakan standar de-facto pada saat ini, akhir 2018).
Catatan yang require_relative
menggunakan direktori file saat ini dengan pernyataan require_relative (jadi tidak harus direktori Anda saat ini dari mana Anda menggunakan perintah). Ini menjaga require_relative
jalur "stabil" karena selalu relatif terhadap file yang membutuhkannya dengan cara yang sama.
Jawaban teratas benar, tetapi sangat teknis. Bagi mereka yang lebih baru ke Ruby:
require_relative
kemungkinan besar akan digunakan untuk membawa kode dari file lain yang Anda tulis. misalnya, bagaimana jika Anda memiliki data ~/my-project/data.rb
dan Anda ingin memasukkannya ke dalam ~/my-project/solution.rb
? di solution.rb
Anda akan menambahkan require_relative 'data'
.
Penting untuk dicatat bahwa file-file ini tidak perlu berada di direktori yang sama. require_relative '../../folder1/folder2/data'
juga valid.
require
kemungkinan besar akan digunakan untuk membawa kode dari perpustakaan yang ditulis orang lain.misalnya, bagaimana jika Anda ingin menggunakan salah satu fungsi pembantu yang disediakan di active_support
perpustakaan? Anda harus menginstal gem dengan gem install activesupport
dan kemudian dalam file require 'active_support'
.
require 'active_support/all'
"FooBar".underscore
Kata berbeda--
require_relative
membutuhkan file yang secara khusus diarahkan ke file yang memanggilnya.
require
membutuhkan file yang disertakan dalam $LOAD_PATH
.
Saya baru saja melihat kode RSpec memiliki beberapa komentar tentang require_relative
menjadi O (1) konstan dan require
menjadi O (N) linier. Jadi mungkin perbedaannya adalah yang require_relative
lebih disukai daripada require
.
require_relative
itu lebih cepat karena loader tidak harus melintasi jalur beban untuk mencari file. Intinya, require_relative
sediakan tautan langsung.
Saya ingin menambahkan bahwa ketika menggunakan Windows Anda dapat menggunakan require './1.rb'
jika skrip dijalankan secara lokal atau dari drive jaringan yang dipetakan tetapi ketika dijalankan dari \\servername\sharename\folder
jalur UNC yang perlu Anda gunakan require_relative './1.rb'
.
Saya tidak bergaul dalam diskusi yang digunakan karena alasan lain.
require_relative
file Bisakah Anda memberikan ide di stackoverflow.com/questions/43487784/…
$:
. Lihat stackoverflow.com/questions/2900370