ruby - 如何存储和读取 RubyVM::InstructionSequence?

标签 ruby yarv

有没有办法将 RubyVM::InstructionSequence 存储到文件中并稍后读取?

我尝试了 Marshal.dump 但没有成功。我收到以下错误:

`dump': no _dump_data is defined for class RubyVM::InstructionSequence (TypeError)

最佳答案

是的,有办法。

首先,您需要使 InstructionSequenceload 方法可访问,默认情况下该方法是禁用的:

require 'fiddle'

class RubyVM::InstructionSequence
  # Retrieve Ruby Core's C-ext `iseq_load' function address
  load_fn_addr  = Fiddle::Handle::DEFAULT['rb_iseq_load']
  # Retrieve `iseq_load' C function representation
  load_fn       = Fiddle::Function.new(load_fn_addr,
                                       [Fiddle::TYPE_VOIDP] * 3,
                                       Fiddle::TYPE_VOIDP)

  # Make `iseq_load' accessible as `load' class method
  define_singleton_method(:load) do |data, parent = nil, opt = nil|
    load_fn.call(Fiddle.dlwrap(data), parent, opt).to_value
  end
end

因为 RubyVM::InstructionSequence.load 方法可以将编译后的 VM 指令作为数组加载,您可以自由地将其用于(反)序列化目的:

irb> # compile simple ruby program into its instruction sequence
irb> seq = RubyVM::InstructionSequence.new <<-EOS
irb:   p 'Hello, world !'
irb:   EOS
=> <RubyVM::InstructionSequence:<compiled>@<compiled>

irb> # serialize sequence as Array instance representation
irb> data = Marshal.dump seq.to_a
=> "\x04\b[\x13\"-YARVInstructionSequence/SimpleDataFormat … ]"

irb> # de-serialize previously serialized sequence
irb> seq_loaded = Marshal.load data
=> ["YARVInstructionSequence/SimpleDataFormat", 2, 2, 1, { … ]

irb> # load deserialized Array back into instruction sequence
irb> new_iseq = RubyVM::InstructionSequence.load seq_loaded
=> <RubyVM::InstructionSequence:<compiled>@<compiled>>

irb> # execute instruction sequence in current context
irb> new_iseq.eval
"Hello, world !"
=> "Hello, world !"

这就是所有人 ;)

关于ruby - 如何存储和读取 RubyVM::InstructionSequence?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30562292/

相关文章:

ruby - 在 ubuntu 16.04 上安装 fpm 时出错

ruby gem : writing tests for api wrapper

ruby-on-rails - 获取每个用户的文件夹大小和所有内容

ruby - 如何在 Ruby 中重新定义 Fixnum 的 + (plus) 方法并保留原始 + 功能?

c++ - 惰性符号绑定(bind)失败 : symbol not found

ruby - MRI 和 YARV Ruby 实现——Ruby 1.9 发生了什么?

ruby-on-rails - 覆盖 Rails ActiveRecord 销毁行为的最佳方法是什么?

ruby - Ruby 中的局部变量传递给 Linux 终端