我正在尝试创建一个扩展FileUtils
类功能的模块。
require 'fileutils'
module FileManager
extend FileUtils
end
puts FileManager.pwd
如果我运行此操作,我将收到private method 'pwd' called for FileManager:Module (NoMethodError)
错误
更新
为什么这些类方法是私有的,如何将所有它们公开,而不必在FileManager模块中手动包含每个方法作为公共类方法?
答案 0 :(得分:2)
require 'fileutils'
module FileManager
extend FileUtils
def FMpwd
pwd
end
module_function :FMpwd
end
puts FileManager.FMpwd
=> /home/rjuneja/Programs/stackoverflow
这部分是因为Ruby将私有和受保护的方法视为与其他语言略有不同。当一个方法在Ruby中声明为private时,意味着永远不能使用显式接收器调用此方法。每当我们能够使用隐式接收器调用私有方法时,它总是会成功。您可以在此处找到更多信息:
为什么不修补FileUtils以包含您想要的方法:
require 'fileutils'
module FileUtils
class << self
def sayHello
puts "Hello World!"
end
end
end
FileUtils.sayHello
=> "Hello World!"
答案 1 :(得分:2)
似乎FileUtils
上的实例方法都是私有的(如此处的另一个答案所述,这意味着它们只能在没有显式接收器的情况下调用)。包含或扩展时获得的是实例方法。例如:
require 'fileutils'
class A
include FileUtils
end
A.new.pwd #=> NoMethodError: private method `pwd' called for #<A:0x0000000150e5a0>
o = Object.new
o.extend FileUtils
o.pwd #=> NoMethodError: private method `pwd' called for #<Object:0x00000001514068>
事实证明我们在FileUtils
上想要的所有方法都有两次,作为私有实例方法,也可以作为公共类方法(也称为单例方法)。
基于this answer我提出了这个代码,基本上将所有类方法从FileUtils
复制到FileManager
:
require 'fileutils'
module FileManager
class << self
FileUtils.singleton_methods.each do |m|
define_method m, FileUtils.method(m).to_proc
end
end
end
FileManager.pwd #=> "/home/scott"
它并不漂亮,但它完成了这项工作(据我所知)。