Dan*_*ley 99 ruby access-specifier private-methods
我有两个问题
最佳实践
这些是我能看到的选项,哪个最好?:
技术部分
有没有办法制作私有模块方法?
module Thing
def self.pub; puts "Public method"; end
private
def self.priv; puts "Private method"; end
end
Run Code Online (Sandbox Code Playgroud)
在private中似乎有没有什么影响,我仍然可以调用Thing.priv没有问题.
小智 85
我认为最好的方法(以及主要是如何编写现有的lib)通过在模块中创建一个处理所有逻辑的类来实现这一点,并且模块只提供了一个方便的方法,例如
module GTranslate
class Translator
def perform( text ); 'hola munda'; end
end
def self.translate( text )
t = Translator.new
t.perform( text )
end
end
Run Code Online (Sandbox Code Playgroud)
小智 75
还有Module.private_class_method,可以说表达了更多的意图.
module Foo
def self.included(base)
base.instance_eval do
def method_name
# ...
end
private_class_method :method_name
end
end
end
Run Code Online (Sandbox Code Playgroud)
对于问题中的代码:
module Thing
def self.pub; puts "Public method"; end
def self.priv; puts "Private method"; end
private_class_method :priv
end
Run Code Online (Sandbox Code Playgroud)
Ruby 2.1或更新版本:
module Thing
def self.pub; puts "Public method"; end
private_class_method def self.priv; puts "Private method"; end
end
Run Code Online (Sandbox Code Playgroud)
cdr*_*rev 49
module Writer
class << self
def output(s)
puts upcase(s)
end
private
def upcase(s)
s.upcase
end
end
end
Writer.output "Hello World"
# -> HELLO WORLD
Writer.upcase "Hello World"
# -> so.rb:16:in `<main>': private method `upcase' called for Writer:Module (NoMethodError)
Run Code Online (Sandbox Code Playgroud)
小智 28
您可以使用"包括"方法做花哨的东西,当一个模块中混合这确实你想要什么,我认为:
module Foo
def self.included(base)
class << base
def public_method
puts "public method"
end
def call_private
private_method
end
private
def private_method
puts "private"
end
end
end
end
class Bar
include Foo
end
Bar.public_method
begin
Bar.private_method
rescue
puts "couldn't call private method"
end
Bar.call_private
Run Code Online (Sandbox Code Playgroud)
J C*_*per 12
不幸的是,private仅适用于实例方法.在类中获取私有"静态"方法的一般方法是执行以下操作:
class << self
private
def foo()
....
end
end
Run Code Online (Sandbox Code Playgroud)
不可否认,我没有在模块中这样做过.