如何在 Ruby 中访问私有 class 方法?
How to access private class methods in Ruby?
在 Ruby 中给定一个 Class:
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
要访问私有方法,我可以在 Class 对象上调用 .send(:my_method)
,但这对 class 方法有何作用?
你应该这样做:
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中,class(s)也是对象,所以你也可以在class上调用#send
方法。
在Ruby中,您可以将私有class方法定义为
class MyClass
class << self
private
def my_class_method
puts "class method"
end
end
end
或使用此 宏 之类的方法:private_class_method
仅供参考,这不是创建私有 class 方法的方式。
class A
private
def self.foo
"foo"
end
end
A.foo # => "foo"
要创建私有class方法,您需要使用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
一切都很好,但为什么这对您的问题很重要?
因为您要在 self
上明确声明 my_class_method
。这样做绕过private
修饰符,方法是public。这意味着您可以调用它:
MyClass.my_class_method
如果你真的需要private
class方法,那么你可以在metaclass:
上定义它们
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"
没有class方法这样的东西。 Class 方法只是 class 的单例方法。但是也没有像单例方法这样的东西。单例方法只是单例的实例方法class。因此,class 方法只是 class 的单例 class.
的实例方法
因为没有class方法,只有实例方法,你已经知道该怎么做了:
To access private methods I can call .send(:my_method)
on the Class Object, but how does that work for class methods?
在 Ruby 中给定一个 Class:
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
要访问私有方法,我可以在 Class 对象上调用 .send(:my_method)
,但这对 class 方法有何作用?
你应该这样做:
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中,class(s)也是对象,所以你也可以在class上调用#send
方法。
在Ruby中,您可以将私有class方法定义为
class MyClass
class << self
private
def my_class_method
puts "class method"
end
end
end
或使用此 宏 之类的方法:private_class_method
仅供参考,这不是创建私有 class 方法的方式。
class A
private
def self.foo
"foo"
end
end
A.foo # => "foo"
要创建私有class方法,您需要使用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
一切都很好,但为什么这对您的问题很重要?
因为您要在 self
上明确声明 my_class_method
。这样做绕过private
修饰符,方法是public。这意味着您可以调用它:
MyClass.my_class_method
如果你真的需要private
class方法,那么你可以在metaclass:
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"
没有class方法这样的东西。 Class 方法只是 class 的单例方法。但是也没有像单例方法这样的东西。单例方法只是单例的实例方法class。因此,class 方法只是 class 的单例 class.
的实例方法因为没有class方法,只有实例方法,你已经知道该怎么做了:
To access private methods I can call
.send(:my_method)
on the Class Object, but how does that work for class methods?