ruby - Ruby 中运行时代码生成的最佳实践

标签 ruby compilation code-generation runtime-compilation

我最近开始研究解析器和解析器生成器以及它们在 DSL 设计中的用途。为了让事情开始,并用一 block 石头杀死两只鸟,我通过窃取 peg.js 的一些想法编写了一个纯 Ruby PEG 解析器 DSL。不同之处在于 peg.js 会将语法编译为 JavaScript,而我的库使用解释器模式结合 Ruby 提供的一些语法糖来在纯 Ruby 中完成所有事情。这增加了一些我想避免的重要开销。

为了减少一些开销,我开始考虑将生成的一些解析表达式编译成较低级别的表示形式。我的一个想法是使用 eval 来评估某个对象的单例类中代码的字符串表示形式。下面是一些伪代码来演示该过程:

# will be used to pass CompiledExpression instance to `eval`
def get_binding(instance)
  instance.instance_eval { binding }
end

# an instance of this class will be used with `eval` 
# to define an `execute` method
class CompiledExpression
  attr_reader :code_repr
  # need to instantiate with a string representation of 
  # the code we are going to use to define the `execute` method
  def initialize(code)
    @code_repr = code
  end
end

# create the instance and define `execute` for that instance
# by evaluating the code representation
compiled_expr = CompiledExpression.new

# first way
eval "class << self; def execute; " +
    "#{compiled_expr.code_repr}; end; end", get_binding(compiled_expr)

# second way
compiled_expr.instance_eval "class << self; " +
    "def execute; #{compiled_expr.code_repr}: end; end"

# third way
compiled_expr.singleton_class.class_eval "def execute; " + 
    "#{compiled_expr.code_repr}; end"

# fourth way
compiled_expr.instance_eval "def execute; " + 
    "#{compiled_expr.code_repr}; end"

我想知道是否有其他/更好的方法来完成这样的代码生成?我是新手,所以我可能遗漏了一些明显的东西。

最佳答案

我仍在尝试了解您要完成的工作,但已经有一些您可能有兴趣探索的 Ruby 解析器/解析器生成器。

Treetop:我最熟悉的解析器,它是一个 peg 解析器,可以动态运行或将语法编译成纯 Ruby 解析器Treetop .

Parslet:这是另一个 peg 解析器,它的设计比 Treetop 更简单,并且错误报告“更好”。 Parslet .

Citrus:另一种解析器,我不太熟悉;不过,我不认为这是一个纯粹的 peg 解析器。 Citrus .

关于ruby - Ruby 中运行时代码生成的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12505122/

相关文章:

ruby-on-rails - Rails 应用程序的入口点在哪里?

android - 如何从源代码编译Android?

java - 在 IntelliJ 插件构建期间运行代码生成器

java - 如何编写在请求正文中接受 XML 的 swagger API

ruby-on-rails - 如何在 Nokogiri 中创建具有属性和值的 xml 元素

ruby - 为什么 __FILE__ 是大写而 __dir__ 是小写?

CUDD 包 : problems compile and makefile

visual-studio - MSVC++ 6.0 : Fatal error C1509 “Too many exception handler states in function”

ruby-on-rails - 使用常量还是类变量?

swift - Swift 的 XCode 7 编译错误