Mở đầu
Trong quá trình lập trình với Ruby, việc chia sẻ và tái sử dụng mã nguồn giữa các file là vô cùng quan trọng. Ba từ khóa chính giúp chúng ta thực hiện điều này là require
, require_relative
và load
. Tuy nhiên, nhiều lập trình viên mới có thể bối rối về sự khác biệt giữa chúng. Bài viết này sẽ giúp bạn hiểu rõ hơn về require
, require_relative
, load
, cách sử dụng chúng một cách hiệu quả, và kèm theo các ví dụ minh họa cụ thể.
Trong bài viết này, giả sử chúng ta có cấu trúc thư mục và file như bên dưới:
1
2
3
4
- project/
- main.rb
- lib/
- foo.rb
1
2
3
4
5
class Foo
def message
puts "Hello world!"
end
end
require trong Ruby
require
là một từ khóa trong Ruby được sử dụng để nạp các thư viện và module vào chương trình hiện tại. Điểm đặc biệt của require
là nó chỉ nạp file một lần duy nhất trong suốt quá trình thực thi chương trình. Điều này giúp tránh việc nạp lại không cần thiết và tiết kiệm tài nguyên hệ thống.
require
sẽ đọc file bạn require và lưu tại bộ nhớ, những lần tiếp theo khi bạn chạy tới file đó, nó sẽ đọc nội dung từ bộ nhớ đã lưu lại tại lần đọc đầu tiên, điều này giúp tăng performance vì không phải load lại file nhiều lần, tuy nhiên những thay đổi sau đó tại file được require sẽ không được cập nhật khi chạy.
Khi sử dụng require
, Ruby sẽ tìm kiếm các file cần nạp trong các đường dẫn được liệt kê trong biến toàn cục $LOAD_PATH
. require
cho phép bỏ qua phần mở rộng .rb
khi gọi file.
Ví dụ về require
Giả sử chúng ta có nội dung file main.rb như sau:
1
2
3
4
require './lib/foo'
foo = Foo.new
foo.message
Khi bạn chạy main.rb, kết quả sẽ là:
1
Hello world!
require_relative trong Ruby
require_relative
tương tự như require
, chỉ nạp file 1 lần duy nhất, nhưng nó nạp file theo đường dẫn tương đối với vị trí của file hiện tại. Điều này hữu ích khi bạn muốn nạp các file trong cùng một dự án mà không cần chỉ định đường dẫn đầy đủ.
Ví dụ về require_relative
Giả sử chúng ta có nội dung file main.rb như sau, và folder project
nằm bên trong folder work
:
1
2
3
4
require_relative './lib/foo'
foo = Foo.new
foo.message
Khi bạn chạy main.rb từ folder root của project, hoặc từ bên ngoài, thì cũng sẽ hiển thị kết quả như mong muốn.
1
2
# work/project/
ruby main.rb => Hello world!
1
2
# work/
ruby project/main.rb => Hello world!
load trong Ruby
load
là một từ khóa trong Ruby được sử dụng để nạp các file mã nguồn vào chương trình hiện tại. Tuy nhiên, khác với require
, load
sẽ nạp lại file mỗi lần nó được gọi. Điều này có nghĩa là nếu nội dung của file thay đổi trong quá trình thực thi, những thay đổi đó sẽ được áp dụng.
Ví dụ về load
Giả sử chúng ta có nội dung file main.rb như sau:
1
2
3
4
load './lib/foo.rb'
foo = Foo.new
foo.message
Khi bạn chạy main.rb, kết quả sẽ được hiển thị.
So sánh require và load
Các từ khóa này đều có tác dụng là nạp những đoạn code cần thiết vào file hiện tại. Có những khác biệt cơ bản:
require
sẽ đọc và nạp file được gọi một lần duy nhất trong suốt quá trình thực thi chương trình.load
sẽ đọc và nạp file mỗi khi file đó được gọi, ngay cả khi nó đã được nạp trước đó.
Vì vậy, load
sẽ hữu dụng hơn khi làm việc tại môi trường phát triển (development), nơi mà thay đổi mã nguồn diễn ra liên tục. Ngược lại, require
thích hợp khi triển khai lên môi trường sản xuất (production), nơi mà mã nguồn ổn định và không thay đổi thường xuyên.
Tổng Kết
Dưới đây là bảng so sánh sự khác nhau giữa ba phương thức require
, require_relative
và load
trong Ruby:
Phương thức | Đường dẫn | Số lần nạp | Bỏ qua phần mở rộng |
---|---|---|---|
require | Đường dẫn tương đối từ vị trí thực thi lệnh Ruby ($LOAD_PATH) | 1 lần duy nhất | Có |
require_relative | Đường dẫn tương đối từ vị trí gọi require_relative |
1 lần duy nhất | Có |
load | Đường dẫn tương đối từ vị trí thực thi lệnh Ruby ($LOAD_PATH) | Mỗi lần gọi đều nạp lại | Không |
Với sự hiểu biết rõ ràng về sự khác biệt này, bạn có thể sử dụng require
, require_relative
, và load
một cách hiệu quả trong các dự án Ruby của mình.