require, load, include, prepend và extend trong Ruby

Các method này đều “đưa code vào đâu đó”, nhưng ở các tầng hoàn toàn khác nhau.

require

1
require "json"

Load feature một lần và ghi vào $LOADED_FEATURES. Dùng cho standard library/gem. Return true khi load mới, false khi đã load.

require_relative

1
require_relative "../lib/parser"

Resolve path tương đối với file hiện tại, phù hợp code project không có load path setup.

load

1
load "script.rb"

Thực thi file mỗi lần gọi. Hữu ích cho script/reloading đặc biệt, không phải import mặc định. load(path, true) wrap trong anonymous module để giảm constant pollution.

include

1
2
3
4
5
6
7
module Trackable
def tracked? = true
end

class Order
include Trackable
end

Đưa module vào ancestor chain cho instance method.

prepend

1
2
3
4
5
6
7
8
module Logging
def call
puts "before"
super
end
end

Service.prepend(Logging)

Module đứng trước class trong lookup chain, phù hợp wrap method bằng super.

extend

1
Order.extend(Trackable)

Include module vào singleton class của object; với class object, methods trở thành class methods.

Mental model

  • require/load: thực thi file.
  • include/prepend/extend: thay đổi method lookup.

Chúng không thay thế nhau. require file định nghĩa module không tự include module đó; Ruby load code nhưng không đoán kiến trúc hộ ta. May mắn thay, vì codebase đã đủ bất ngờ rồi.

Reference