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
但是,我强烈建议不要做这两件事。最好创建一个封装数组的对象,并且只提供您需要的方法:
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
没有任何作用。
您已经定义了一个包含 parse_test
方法的新类TestParser::Array
;您尚未修改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 类是位于继承链最顶端的常量,因此 AnonymousClass 中的Array
常量隐藏了 Array 类中内置的 Ruby。 要引用 Array 类中内置的 ruby,您必须编写::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
*政变恩典:结束重伤者或动物痛苦的致命一击