我有以下代码:
#!/usr/bin/ruby
class Person
def self.speak
p = self.new
puts "Hello"
p.chatter
end
private
def chatter
puts "Chattering"
end
end
p = Person.new
Person.speak
我想让聊天私密,只能在p内访问..但我希望p能够在类方法中访问它。有没有更好的方法来设计这个,所以公众无法获得聊天,但像self.speak这样的“工厂”方法可以调用聊天?
答案 0 :(得分:8)
在Ruby 1.8.7中,“发送”绕过了对调用私有方法的常规保护:
#!/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
也绕过了对私人方法的保护。
答案 1 :(得分:1)
有很多方法可以做到这一点。一种方法是实例化新实例并在实例上调用#speak
方法的类方法。
class Person
def self.speak
new.speak
end
def speak
puts "Hello"
chatter
end
private
def chatter
puts "Chattering"
end
end
然后你可以在类或实例上下文中调用它:
p = Person.new
p.speak
# ...or...
Person.speak