我有两个问题
最佳实践
我有一个算法,使用公共接口对数据结构执行某些操作
它目前是一个具有许多静态方法的模块,除了一个公共接口方法之外都是私有的.
有一个实例变量需要在所有方法之间共享.
这些是我能看到的选项,哪个最好?:
模块与静态(红宝石"模块")的方法
使用静态方法的类
Mixin模块包含在数据结构中
重构修改该数据结构的算法部分(非常小)并使其成为调用算法模块的静态方法的mixin
技术部分
有没有办法制作私有模块方法?
module Thing def self.pub; puts "Public method"; end private def self.priv; puts "Private method"; end end
在private
中似乎有没有什么影响,我仍然可以调用Thing.priv
没有问题.
我认为最好的方法(以及主要是如何编写现有的lib)通过在模块中创建一个处理所有逻辑的类来实现这一点,并且模块只提供了一个方便的方法,例如
module GTranslate class Translator def perform( text ); 'hola munda'; end end def self.translate( text ) t = Translator.new t.perform( text ) end end
还有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
对于问题中的代码:
module Thing def self.pub; puts "Public method"; end def self.priv; puts "Private method"; end private_class_method :priv end
Ruby 2.1或更新版本:
module Thing def self.pub; puts "Public method"; end private_class_method def self.priv; puts "Private method"; end end
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 `': private method `upcase' called for Writer:Module (NoMethodError)
您可以使用"包括"方法做花哨的东西,当一个模块中混合这确实你想要什么,我认为:
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
不幸的是,private
仅适用于实例方法.在类中获取私有"静态"方法的一般方法是执行以下操作:
class << self private def foo() .... end end
不可否认,我没有在模块中这样做过.