class Check
include TestParser
# so on
end
和模块结构:
module TestParser
class Array
def parse_test
# method
end
end
end
我想要实现的是文件 check.rb 中的每个数组都可以通过parse_test
方法调用。
我哪里弄错了?(抛出未定义的方法错误)
class Check
include TestParser
# so on
end
和模块结构:
module TestParser
class Array
def parse_test
# method
end
end
end
我想要实现的是文件 check.rb 中的每个数组都可以通过parse_test
方法调用。
我哪里弄错了?(抛出未定义的方法错误)
您正在寻找的是Ruby 2.0 的改进。请注意,此功能是实验性的:
module TestParser
refine Array do
def parse_test
42
end
end
end
using TestParser # This applies only to the current file
class Check
[].parse_test #=> 42
end
您还可以从 Array 继承并添加您的方法:
class TestParser < Array
def parse_test
42
end
end
arr = TestParser.new
arr.is_a? Array #=> true
arr.parse_test #=> 42
但是,我强烈反对做这些事情中的任何一个。最好做一个封装了 Array 并且只提供你需要的方法的对象:
class TestParser
def initialize array = []
@array = array
end
def parse_test
# do stuff to @array
end
end
最后,为什么你所拥有的东西不起作用:
module TestParser
class Array
def parse_test; end
end
end
创建了两件事:一个TestParser
没有方法的模块和一个TestParser::Array
只有一个方法的类(parse_test
)。由于TestParser
没有方法,将其包含到另一个模块/类中对可用的方法没有影响。包括TestParser
不做任何事情TestParser::Array
。
您已经定义了一个TestParser::Array
包含该parse_test
方法的新类;你还没有修改Array
类。
您也可能会混淆模块和包含。
如果您的目标是将方法添加parse_test
到 Ruby 程序中的数组中,您可以将其放在一个名为 的文件test_parser.rb
中,无需模块声明:
class Array
def parse_test
# method
end
end
但这会修改Array
你说你不想做的基类。此外,一旦文件为 require
d,它将立即进行修改。不需要包含。
在当前实验性的 Ruby 2.0 特性(称为细化)之外,没有办法将这些类型的修改本地化到基类(称为“猴子补丁”)。
如果您希望数组的行为不同但仅在您的代码中,您最好的办法是定义您自己的扩展 Array 的类(也就是说,使其成为一个容器类包装并委托给一个常规的Array
,或者如果您觉得必须是一个子类) .
我想要实现的是文件 check.rb 中的每个数组都可以通过 parse_test 方法调用。
你只需要知道如何创建数组:
module TestParser
class Array
def parse_test
puts 'hello'
end
end
end
class Check
include TestParser
Array.new.parse_test
def do_stuff
Array.new.parse_test
end
end
Check.new.do_stuff
Check::Array.new.parse_test
--output:--
hello
hello
hello
当然,TestParser::Array 类没有 Array 类中的任何方法:
module TestParser
class Array
def parse_test
puts 'hello'
end
end
end
TestParser::Array.new.parse_test
TestParser::Array.new.size
--output:--
hello
1.rb:11:in `<main>': undefined method `size' for #<TestParser::Array:0x00000101141700> (NoMethodError)
那是因为您在命名空间 TestParser 中创建了一个新的 Array 类——您没有重新打开 ruby 内置的 Array 类。
那么当你写的时候include TestParser
,就相当于这样做了:
class AnonymousClass
class Array
def parse_test
puts 'hello'
end
end
end
class Check < AnonymousClass
Array.new.parse_test
end
当在 Check 中找不到常量时,ruby 会沿着继承链向上寻找常量:
class Parent
CONST = 10
end
class Child < Parent
puts CONST
end
--output:--
10
因为内置的 Array 类是位于继承链最顶端的Array
常量,所以 AnonymousClass 中的常量隐藏了 Ruby 内置的 Array 类。要引用 Ruby 内置的 Array 类,您必须编写::Array
:
module TestParser
class Array
def parse_test
puts 'hello'
end
end
end
class Check
include TestParser
p Array
p ::Array
end
--output:--
TestParser::Array
Array
对于政变*:
module TestParser
class Array
def parse_test
puts 'hello'
end
end
end
class Check
include TestParser
end
puts TestParser::Array.object_id
puts Check::Array.object_id
--output:--
2152779400
2152779400
*致命一击:结束重伤人员或动物痛苦的致命一击