有一个我需要解析的 DSL ruby 文件。看起来像
# file B.rb
class B < A
hello "John"
end
hello "Mary"
它在类 B
的内部和外部调用带有字符串参数的函数 hello()
。
我尝试require
文件B.rb
并解决缺少的方法:
# file A.rb
# define a class A for subclassing, before loading B.rb
class A
end
# Try to catch the missing methods
def method_missing(name, *args, &block)
puts "tried to handle unknown method %s" % name # name is a symbol
end
require("./B.rb")
运行此代码后,method_missing
会导致无限循环。
如何捕获并解析类B
内部和外部的未定义方法?我想知道DSL文件中调用了哪些方法和参数。
最佳答案
我在评论中暗示了这种方法,但认为详细说明可能有用。
所以首先我们需要在某些东西上定义method_missing
,我们不能在顶层定义它,因为我们会收到这个警告
redefining Object#method_missing may cause infinite loop
相反,我们将在类 A
上定义它(在类级别)。
# in a.rb
class A
def self.method_missing(name, *args, &block)
puts "tried to handle unknown method %s" % name # name is a symbol
end
end
现在我们可以使用 class_eval
在 class A
范围内评估 b.rb
,如下所示:
# also in a.rb
A.class_eval(File.read("./b.rb"))
现在,“顶级”hello "Mary"
调用实际上是在 A
的类作用域中执行的(其中 method_missing
定义活跃)。此外,由于 class B
继承自 A
,它在类级别上也有 method_missing
定义,因此 hello "John"
调用也会命中它。
因此,运行脚本,我看到 tried to handleknown method hello
按预期打印了两次。
我应该注意,我认为以这种方式“忽略”错误不是一个好主意......很可能最好停止程序的执行。但也许你心里有一些需要它的东西,我不能确定。
关于Ruby:在需要子类文件时如何捕获和解析未定义的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65403255/