Sự khác biệt giữa require_relative
và require
trong Ruby là gì?
Sự khác biệt giữa require_relative
và require
trong Ruby là gì?
Câu trả lời:
Chỉ cần nhìn vào các tài liệu :
require_relative
bổ sung cho phương thức dựng sẵnrequire
bằng cách cho phép bạn tải một tệp có liên quan đến tệp chứarequire_relative
câu lệnh.Ví dụ: nếu bạn có các lớp kiểm tra đơn vị trong thư mục "kiểm tra" và dữ liệu cho chúng trong thư mục "kiểm tra / dữ liệu" kiểm tra, thì bạn có thể sử dụng một dòng như thế này trong trường hợp kiểm tra:
require_relative "data/customer_data_1"
require './file.rb'
và require_relative 'file.rb'
?
require_relative
cho phép bạn "tải một tệp có liên quan đến tệp chứa require_relative
câu lệnh ". Với require
, ./
chỉ ra một đường dẫn có liên quan đến thư mục làm việc hiện tại của bạn.
require str
sẽ luôn tìm kiếm thông qua các thư mục trong $ LOAD_PATH. Bạn nên sử dụng require_relative
khi tệp bạn cần tải tồn tại ở đâu đó so với tệp yêu cầu tải. Dự trữ require
cho các phụ thuộc "bên ngoài".
require_relative
là một tập hợp con thuận tiện của require
require_relative('path')
bằng:
require(File.expand_path('path', File.dirname(__FILE__)))
nếu __FILE__
được định nghĩa, hoặc nó tăng LoadError
khác.
Điều này ngụ ý rằng:
require_relative 'a'
và require_relative './a'
yêu cầu liên quan đến tập tin hiện tại ( __FILE__
).
Đây là những gì bạn muốn sử dụng khi yêu cầu trong thư viện của mình, vì bạn không muốn kết quả phụ thuộc vào thư mục hiện tại của người gọi.
eval('require_relative("a.rb")')
tăng LoadError
vì __FILE__
không được xác định bên trong eval
.
Đây là lý do tại sao bạn không thể sử dụng require_relative
trong các thử nghiệm RSpec, có được eval
ed.
Các hoạt động sau đây chỉ có thể với require
:
require './a.rb'
yêu cầu liên quan đến thư mục hiện tại
require 'a.rb'
sử dụng đường dẫn tìm kiếm ( $LOAD_PATH
) để yêu cầu. Nó không tìm thấy các tập tin liên quan đến thư mục hoặc đường dẫn hiện tại.
Điều này là không thể require_relative
bởi vì các tài liệu nói rằng tìm kiếm đường dẫn chỉ xảy ra khi "tên tệp không phân giải thành một đường dẫn tuyệt đối" (nghĩa là bắt đầu bằng /
hoặc ./
hoặc ../
), luôn luôn là trường hợp File.expand_path
.
Hoạt động sau đây có thể với cả hai, nhưng bạn sẽ muốn sử dụng require
vì nó ngắn hơn và hiệu quả hơn:
require '/a.rb'
và require_relative '/a.rb'
cả hai đều yêu cầu con đường tuyệt đối.Đọc nguồn
Khi tài liệu không rõ ràng, tôi khuyên bạn nên xem các nguồn (chuyển nguồn trong tài liệu). Trong một số trường hợp, nó giúp hiểu những gì đang xảy ra.
yêu cầu:
VALUE rb_f_require(VALUE obj, VALUE fname) {
return rb_require_safe(fname, rb_safe_level());
}
Yêu cầu: có liên quan:
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());
}
Điều này cho phép chúng tôi kết luận rằng
require_relative('path')
giống như:
require(File.expand_path('path', File.dirname(__FILE__)))
bởi vì:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
Từ API Ruby :
allow_relative bổ sung cho phương thức dựng sẵn yêu cầu bằng cách cho phép bạn tải một tệp có liên quan đến tệp có chứa câu lệnh allow_relative.
Khi bạn sử dụng yêu cầu tải tệp, bạn thường truy cập chức năng đã được cài đặt đúng cách và có thể truy cập được trong hệ thống của bạn. yêu cầu không cung cấp một giải pháp tốt để tải các tệp trong mã của dự án. Điều này có thể hữu ích trong giai đoạn phát triển, để truy cập dữ liệu thử nghiệm hoặc thậm chí để truy cập các tệp bị "khóa" bên trong dự án, không dành cho sử dụng bên ngoài.
Ví dụ: nếu bạn có các lớp kiểm tra đơn vị trong thư mục "kiểm tra" và dữ liệu cho chúng trong thư mục "kiểm tra / dữ liệu" kiểm tra, thì bạn có thể sử dụng một dòng như thế này trong trường hợp kiểm tra:
require_relative "data/customer_data_1"
Vì cả "test" hay "test / data" đều không có khả năng nằm trong đường dẫn thư viện của Ruby (và vì lý do chính đáng), nên một yêu cầu bình thường sẽ không tìm thấy chúng. Yêu cầu là một giải pháp tốt cho vấn đề cụ thể này.
Bạn có thể bao gồm hoặc bỏ qua phần mở rộng (.rb hoặc .so) của tệp bạn đang tải.
đường dẫn phải trả lời to_str.
Bạn có thể tìm thấy tài liệu tại http://extensions.rubyforge.org/rdoc/groupes/Kernel.html
require
cho đá quý được cài đặtrequire_relative
cho các tệp cục bộrequire
sử dụng của bạn $LOAD_PATH
để tìm các tập tin.
require_relative
sử dụng vị trí hiện tại của tệp bằng cách sử dụng câu lệnh
Yêu cầu phụ thuộc vào bạn đã cài đặt (ví dụ gem install [package]
) một gói ở đâu đó trên hệ thống của bạn cho chức năng đó.
Khi sử dụng, require
bạn có thể sử dụng ./
định dạng "" cho một tệp trong thư mục hiện tại, ví dụ: require "./my_file"
nhưng đó không phải là cách làm phổ biến hoặc được khuyến nghị và bạn nên sử dụng require_relative
thay thế.
Điều này chỉ có nghĩa là bao gồm tệp 'liên quan đến vị trí của tệp với câu lệnh notify_relative'. Tôi thường khuyên các tệp nên "trong" cây thư mục hiện tại thay vì "lên", ví dụ: không sử dụng
require_relative '../../../filename'
(tăng 3 cấp độ thư mục) trong hệ thống tệp vì điều đó có xu hướng tạo ra các phụ thuộc không cần thiết và dễ vỡ. Tuy nhiên, trong một số trường hợp nếu bạn đã 'sâu' trong cây thư mục thì "lên và xuống" một nhánh cây thư mục khác có thể là cần thiết. Đơn giản hơn có lẽ, không sử dụng allow_relative cho các tệp bên ngoài kho lưu trữ này (giả sử bạn đang sử dụng git, phần lớn là một tiêu chuẩn không chính thức tại thời điểm này, vào cuối năm 2018).
Lưu ý rằng require_relative
sử dụng thư mục hiện tại của tệp với câu lệnh allow_relative (vì vậy không nhất thiết là thư mục hiện tại của bạn mà bạn đang sử dụng lệnh từ). Điều này giữ cho require_relative
đường dẫn "ổn định" vì nó luôn luôn liên quan đến tệp yêu cầu nó theo cùng một cách.
Các câu trả lời hàng đầu là chính xác, nhưng kỹ thuật sâu sắc. Đối với những người mới hơn với Ruby:
require_relative
rất có thể sẽ được sử dụng để mang mã từ một tệp khác mà bạn đã viết. ví dụ, nếu bạn có dữ liệu ~/my-project/data.rb
và bạn muốn đưa dữ liệu đó vào ~/my-project/solution.rb
thì sao? trong solution.rb
bạn sẽ thêm require_relative 'data'
.
điều quan trọng cần lưu ý là các tệp này không cần phải nằm trong cùng một thư mục. require_relative '../../folder1/folder2/data'
cũng có giá trị
require
rất có thể sẽ được sử dụng để mang mã từ thư viện mà người khác đã viết.ví dụ, nếu bạn muốn sử dụng một trong các hàm trợ giúp được cung cấp trong active_support
thư viện thì sao? bạn sẽ cần cài đặt đá quý với gem install activesupport
và sau đó trong tệp require 'active_support'
.
require 'active_support/all'
"FooBar".underscore
Nói khác đi--
require_relative
yêu cầu một tệp được chỉ định cụ thể liên quan đến tệp gọi nó.
require
yêu cầu một tập tin bao gồm trong $LOAD_PATH
.
Tôi chỉ thấy mã của RSpec có một số nhận xét về require_relative
hằng số O (1) và require
là O (N) tuyến tính. Vì vậy, có lẽ sự khác biệt là đó require_relative
là một trong những ưa thích hơn require
.
require_relative
là nhanh hơn vì trình tải không phải đi qua đường tải trong tìm kiếm tệp. Về cơ bản, require_relative
cung cấp một liên kết trực tiếp.
Tôi muốn thêm rằng khi sử dụng Windows, bạn có thể sử dụng require './1.rb'
nếu tập lệnh được chạy cục bộ hoặc từ ổ đĩa mạng được ánh xạ nhưng khi chạy từ \\servername\sharename\folder
đường dẫn UNC bạn cần sử dụng require_relative './1.rb'
.
Tôi không hòa mình vào cuộc thảo luận sẽ sử dụng cho những lý do khác.
require_relative
tập tin mà bạn có thể xin vui lòng ném một ý tưởng ở đây stackoverflow.com/questions/43487784/...
$:
. Xem stackoverflow.com/questions/2900370