我试图在模块中扩展File
类。这是我的(缩写)代码:
module Wireshark
# Extend the file class to write a header comment
class File
def write_header
self.puts '/* ' + Wireshark::AUTOGEN_LABEL + ' */'
self.puts '/* ' + Wireshark::timestamp + ' */'
end
end
# Read a file
def read
begin
file = File.read 'file'
rescue IOError
STDERR.puts 'Error reading file.'
return
end
end
end
当我运行我的代码时,我正在
undefined method `read' for Wireshark::File:Class (NoMethodError)
当我尝试运行file.read
时。我试图摆脱模块封装,但我只想扩展模块中的File
类,而不是我程序的其余部分。
答案 0 :(得分:1)
你关闭了。
module Wireshark
module File
def write_header
self.puts '/* ' + Wireshark::AUTOGEN_LABEL + ' */'
self.puts '/* ' + Wireshark::timestamp + ' */'
end
end
# Extend File with the methods in the Wireshark::File module
::File.send :include, Wireshark::File
# Read a file
def read
begin
file = ::File.read 'file'
rescue IOError
STDERR.puts 'Error reading file.'
return
end
end
end
这里的一般想法是我们定义一个Wireshark::File
模块,它包含你想要包含在File
类中的方法,然后你可以直接将它们包含在File中。
您还会注意到,在read
方法中,我将File
更改为::File
。 Ruby将在树上向上试图找到给定常量的最近匹配值,因此,由于您位于Wireshark
模块中,并且该范围中有一个名为File
的常量,因此只使用{ {1}}获取File
。指定Wireshark::File
表示"顶级命名空间中的::File
常量"。
答案 1 :(得分:0)
在当前版本的Ruby中,不可能这样做,但它是一个受欢迎的proposed extension called "refinements"。
如果需要修补核心File
类,则需要将其作为猴子补丁进行修补,这会影响Ruby进程中任何位置File
的所有实例。
通常你可以这样做:
# Define the instance methods you want to overide
module MyFileHacksInstanceMethods
def read
# ... (reimplementation) ...
end
end
# Force load these in the File class
class File
include MyFileHacksInstanceMethods
end
您在此示例中声明的是一个名为Wireshark::File
的独立类,因为它位于该模块的命名空间内。 ::File
是主类(::
是强制绝对名称的前缀,类似于文件系统的/
。