Cả hai đều gọi method theo tên động (string/symbol), nhưng:
- send gọi được cả private và protected method.
- public_send chỉ gọi public method — raise NoMethodError nếu method là private.
ruby
class Vault
def open = "opened"
private
def secret = "top secret"
end
v = Vault.new
v.send(:open) # => "opened"
v.send(:secret) # => "top secret" — bypass private!
v.public_send(:secret) # => NoMethodError: private method calledDùng public_send trong production — tôn trọng visibility, an toàn khi input đến từ ngoài.
- Dùng
sendtrong test (spy on private) hoặc khi thực sự cần bypass (hiếm). - Cảnh báo: luôn whitelist method name khi tên đến từ user để tránh code injection.
Both call a method by dynamic name (string/symbol), but:
- send invokes private and protected methods too.
- public_send only calls public methods — raises NoMethodError for private ones.
ruby
class Vault
def open = "opened"
private
def secret = "top secret"
end
v = Vault.new
v.send(:open) # => "opened"
v.send(:secret) # => "top secret" — bypasses private!
v.public_send(:secret) # => NoMethodError: private method calledUse public_send in production — respects visibility, safe when method names come from external input.
- Use
sendin tests (spy on private) or when bypassing visibility is truly required (rare). - Always whitelist method names from user input to avoid code injection.