Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby中运行时代码生成的最佳实践_Ruby_Compilation_Code Generation_Runtime Compilation - Fatal编程技术网

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

Ruby中运行时代码生成的最佳实践,ruby,compilation,code-generation,runtime-compilation,Ruby,Compilation,Code Generation,Runtime Compilation,我最近开始研究解析器和解析器生成器及其在DSL设计中的应用。为了开始工作,一举两得,我从PEG.js中窃取了一些想法,编写了一个纯Ruby PEG解析器DSL。不同之处在于peg.js将把语法编译成JavaScript,而我的库使用解释器模式结合Ruby提供的一些语法糖,在纯Ruby中完成所有事情。这增加了一些我希望避免的非琐碎开销 为了减少一些开销,我开始考虑编译一些生成为较低级别表示的解析表达式。我的一个想法是使用eval在某个对象的单例类中计算代码的字符串表示形式。下面是一些伪代码来演示该

我最近开始研究解析器和解析器生成器及其在DSL设计中的应用。为了开始工作,一举两得,我从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"
#将用于将CompiledExpression实例传递给'eval'`
def get_绑定(实例)
instance.instance_eval{binding}
结束
#此类的实例将与'eval'一起使用
#定义“execute”方法的步骤
类编译表达式
属性读取器:代码报告
#需要使用的字符串表示形式实例化
#我们将要用来定义“execute”方法的代码
def初始化(代码)
@代码_repr=代码
结束
结束
#创建实例并为该实例定义“执行”
#通过评估代码表示
compiled_expr=CompiledExpression.new
#第一条路

eval“class我仍在试图理解您要实现的目标,但是已经有一些Ruby解析器/解析器生成器您可能有兴趣进行探索

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

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


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

我知道所有这些库。我只是重新发明轮子,从更深的层次上学习一些东西。我试图找出在Ruby中运行时生成代码的最佳方法。我想知道是否有更好的方法/生成代码的简单方法,而不是用实际代码计算字符串。