ruby – 文件私有方法

在ruby中,有没有办法定义文件(或模块)中每个类可见的方法,而不是需要文件的文件?

相关但不完全相同:我们可以重新定义一个方法(例如来自标准库类的方法),这样重新定义只在当前文件中可见吗? 所有其他文件应查看原始定义。

不,不。

Ruby中唯一可见的是公共,受保护和私有。 没有文件级可见性的概念。 你可以“欺骗”并做这样的事情:

# In some file foobar.rb class Foo def to_bar Bar.new.file_private end end class Bar def file_private raise unless caller[0].split(':')[0] == __FILE__ end end 
 # In IRB or some other file Foo.new.to_bar #=> nil Bar.new.file_private #=> RuntimeError 

但这是个坏主意。 不同目录中的同名文件可能有效。 它也不是真正的可见性,而是在方法本身中强制执行它。

但实际上,你应该将每个类都放在自己的文件中。 它使组织变得更好。 此外,您不应该依赖公共/受保护/私人。 你总是可以使用send调用私有方法,但上面打破了这种期望。 如果您的代码的用户真的想要对您的代码执行某些操作,那么让他们执行此操作几乎没有任何意义,这就是动态语言的本质。 如果你没有记录方法,大多数用户甚至都不知道它在那里:P

至于你的第二个问题,没有办法在同一个类中有两个具有不同可见性的同名方法,第二个方法将始终覆盖原始方法。 你可以做一些类似于我上面所做的事情,并根据条件运行不同的代码而不是提高,但如上所述我并不认为这是一个好主意。

  1. 在Object类中定义一个新方法(如属性)。 如果您不想弄乱Object类,可以使用其他名称,Foo应该inheritance该类。

     class Object @@file_only_methods = [] def file_only(method_name) method_name = method_name.to_sym new_method_name = "file_only_#{method_name}".to_sym self.send(:alias_method, new_method_name, method_name) self.send(:undef_method, method_name) self.send(:private, new_method_name) @@file_only_methods << method_name end def method_missing(method_name, *arg, &block) if @@file_only_methods.include? method_name if __FILE__ == $0 self.send("file_only_#{method_name}".to_sym,*arg,&block) else raise "Method #{method_name} is called outside the definition file." end else raise "Method #{method_name} does not exist." end end end class Foo def bar puts 'bar method' end file_only :bar end Foo.new.bar #output:bar method Foo.new.x #output:no method 

    在file2.rb中,

     require_relative 'file1' Foo.new.bar #output: Method bar is called outside the definition file.