[英]How to access private class methods in Ruby?
Given a Class in 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
To access private methods I can call .send(:my_method)
on the Class Object, but how does that work for class methods? 要访问私有方法,我可以在类对象上调用
.send(:my_method)
,但是这对于类方法有什么用呢?
You should do: 你应该做:
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
In Ruby, class(s) are also objects, so you can call the #send
method on the class also. 在Ruby中,类也是对象,因此您也可以在类上调用
#send
方法。
In Ruby, you can define private class methods as 在Ruby中,您可以将私有类方法定义为
class MyClass
class << self
private
def my_class_method
puts "class method"
end
end
end
Or using thhis macro like method: private_class_method 或者像方法一样使用宏 : private_class_method
Just for reference, that's not how you create a private class method. 仅供参考,这不是您创建私有类方法的方式。
class A
private
def self.foo
"foo"
end
end
A.foo # => "foo"
To create a private class method, you need to use private_class_method . 要创建私有类方法,需要使用private_class_method 。
class A
def self.foo
"foo"
end
private_class_method :foo
end
A.foo # => private method `foo' called for A:Class
First off, MyClass.send(:my_method)
would not work. 首先,
MyClass.send(:my_method)
不起作用。 You have to send it to an instance: MyClass.new.send(:my_method)
. 您必须将它发送到一个实例:
MyClass.new.send(:my_method)
。
Then, your my_class_method
is not really private. 然后,你的
my_class_method
不是真的私有。
Ruby's semantic of private
are somewhat different from what you might be used to in other languages. Ruby的
private
语义与您在其他语言中的习惯有所不同。 Since Ruby allows you to bypass encapsulation if you choose to, private
just means that a method can only be called implicitly , without sending a message to an actual object. 由于Ruby允许您在选择时绕过封装,因此
private
只意味着只能隐式调用方法,而不向实际对象发送消息。
For example: 例如:
class Example
def test
'foobar'
end
def hello
puts test # implicit receiver
puts self.test # explicit receiver
end
end
This is all good, but why is this important for your question? 这一切都很好,但为什么这对你的问题很重要?
Because you're declaring my_class_method
explicitly on self
. 因为你宣布
my_class_method
上明确self
。 Doing so bypasses the private
modifier, and the method is public. 这样做会绕过
private
修饰符,并且该方法是公共的。 This means that you can just call it with: 这意味着您可以通过以下方式调用它:
MyClass.my_class_method
If you really need private
class methods, then you can define them on the metaclass: 如果你真的需要
private
类方法,那么你可以在元类上定义它们:
class MyClass
class << self
private
def my_class_method
puts "class method"
end
end
private
def my_method
puts "regular method"
end
end
This will make my_class_method
actually private, and force you to invoke it with any of these: 这将使
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"
There are no such things as class methods. 没有类方法这样的东西。 Class methods are just singleton methods of the class.
类方法只是类的单例方法。 But there are no such things as singleton methods either.
但是也没有单身方法这样的东西。 Singleton methods are just instance methods of the singleton class.
单例方法只是单例类的实例方法。 So, class methods are just instance methods of the class's singleton class.
因此,类方法只是类的单例类的实例方法。
Since there is no such thing as a class method, only instance methods, you already know what to do: 由于没有类方法,只有实例方法,你已经知道该怎么做了:
To access private methods I can call
.send(:my_method)
on the Class Object, but how does that work for class methods?要访问私有方法,我可以在类对象上调用
.send(:my_method)
,但是这对于类方法有什么用呢?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.