В Ruby 1.8.7 «send» обходит обычную защиту от вызова приватных методов:
#!/usr/bin/ruby1.8
class Person
def self.speak
puts "Hello"
new.send(:chatter)
end
def speak
puts "Hello"
puts chatter
end
private
def chatter
puts "Chattering"
end
end
Person.speak # => Hello
# => Chattering
Person.new.speak # => Hello
# => Chattering
Однако то, что вы хотите, может быть достигнуто без какого-либо вуду, просто заставив метод класса выполнить всю работу, а метод экземпляра отложить до метода класса:
class Person
def self.speak
puts "Hello"
puts "Chatter"
end
def speak
self.class.speak
end
end
Если у вас было несколько таких методов переадресации, было бы удобно создать вспомогательный метод, который сделает их для вас:
module DelegateToClass
def delegate_to_class(name)
define_method(name) do |*args|
self.class.send(name, *args)
end
end
end
class Person
extend DelegateToClass
def self.speak
puts "Hello"
puts "Chatter"
end
delegate_to_class :speak
end
Встроенный модуль Forwardable
может сделать это так же:
require 'forwardable'
class Person
extend Forwardable
def self.speak
puts "Hello"
puts "Chatter"
end
def_delegator self, :speak
end
def_delegator
также обходит защиту от частных методов.