如何在Ruby中访问私有类方法?
给出Ruby中的一个类:
class MyClass def self.my_class_method puts "class method" end private def my_method puts "regular method" end private_class_method :my_class_method end
要访问私有方法,我可以在类对象上调用.send(:my_method)
,但这对类方法有什么.send(:my_method)
?
你应该做:
class MyClass def self.my_class_method puts "class method" end private def my_method puts "regular method" end private_class_method :my_class_method end # to call class method MyClass.send :my_class_method # => class method # to call instance method MyClass.new.send :my_method # => regular method
在Ruby中,类也是对象,因此您也可以在类上调用#send
方法。
在Ruby中,您可以将私有类方法定义为
class MyClass class << self private def my_class_method puts "class method" end end end
或者像方法一样使用宏 : private_class_method
仅供参考,这不是您创建私有类方法的方式。
class A private def self.foo "foo" end end A.foo # => "foo"
要创建私有类方法,您需要使用private_class_method 。
class A def self.foo "foo" end private_class_method :foo end A.foo # => private method `foo' called for A:Class
首先, MyClass.send(:my_method)
不起作用。 您必须将它发送到一个实例: MyClass.new.send(:my_method)
。
然后,你的my_class_method
不是真的私有。
Ruby的private
语义与您在其他语言中的习惯有所不同。 由于Ruby允许您在选择时绕过封装,因此private
只意味着只能隐式调用方法,而不向实际对象发送消息。
例如:
class Example def test 'foobar' end def hello puts test # implicit receiver puts self.test # explicit receiver end end
这一切都很好,但为什么这对你的问题很重要?
因为你在my_class_method
明确声明了my_class_method
。 这样做会绕过 private
修饰符,并且该方法是公共的。 这意味着您可以通过以下方式调用它:
MyClass.my_class_method
如果你真的需要private
类方法,那么你可以在元类上定义它们:
class MyClass class << self private def my_class_method puts "class method" end end private def my_method puts "regular method" end end
这将使my_class_method
实际上是私有的,并强制您使用以下任何一个来调用它:
MyClass.send :my_class_method MyClass.class_exec { my_class_method } MyClass.class_eval { my_class_method } MyClass.class_eval "my_class_method"
没有类方法这样的东西。 类方法只是类的单例方法。 但也没有单身方法这样的东西。 单例方法只是单例类的实例方法。 因此,类方法只是类的单例类的实例方法。
由于没有类方法,只有实例方法,你已经知道该怎么做了:
要访问私有方法,我可以在类对象上调用
.send(:my_method)
,但这对类方法有什么.send(:my_method)
?