Ruby:在需要子类文件时如何捕获和解析未定义的方法

标签 ruby dsl

有一个我需要解析的 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_evalclass 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/

相关文章:

SQL 'while' 条件

ruby - 安装了哪个 ruby 版本?

ruby-on-rails - 将已编辑的值 contenteditable 字段从 View 传递到 Rails 中的 Controller

groovy - 是否可以在 Groovy 中定义新的运算符?

python - 当一个 DSL 得到 'lispy'

C++ 表达式作为变量

ruby-on-rails - Ruby/Rails,用引号之间的换行符解析 CSV

ruby-on-rails - 重新定义关注的 default_scope(在 Rails 中)

scala - Scala : Lists without "," 中的内部 DSL

java - 构建器模式和 DSL 是等效的——还是更具表现力?