我正在对 Ruby 语言的一些核心组件进行猴子修补(我知道,我知道,monkeypatching 很糟糕) - 我特别需要做的是挂钩:
"#{some_variable}"
我天真的方法是用白夸克解析器 gem 解析 AST 并将所有 #{} 重写为 concats(它确实有效),但我不喜欢这条路线的一些要求(猴子修补很多其他东西以获得每个加载文件[问题列表继续])。
我已经深入研究了 ruby C 代码,但无法找到实际执行插值的函数。任何人都可以帮助我确定该行为的定义位置/方式吗?
编辑:我想要实现的目标,就像你可以做的一样:
class String
alias_method :my_+, :+
def +(other)
puts 'patched'
self.my_+(other)
end
end
a = "a"
a + "b" => #would output patched
我想要一种类似的方法来修补 #{} - 但是,这不能通过正常的猴子修补来完成 - 我正在寻找有关如何在不重写 VM 中每个类的 AST 的情况下实现这一目标的一般指导。
"str1 #{funcall} str2"
在 Ruby 中执行以下操作:
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,24)>=================
0000 putobject "str1 " ( 1)[Li]
0002 putself
0003 opt_send_without_block <callinfo!mid:funcall, argc:0, FCALL|VCALL|ARGS_SIMPLE>, <callcache>
0006 dup
0007 branchiftype T_STRING, 15
0010 dup
0011 opt_send_without_block <callinfo!mid:to_s, argc:0, FCALL|ARGS_SIMPLE>, <callcache>
0014 tostring
0015 putobject " str2"
0017 concatstrings 3
0019 leave
有很多操作(如果不是字符串,则将 #{} 内容转换为字符串),它以 concatstrings 命令结束,根据此命令:http ://lifegoo.pluskid.org/upload/doc/yarv/yarv_iset.html #detail-19调用rb_str_append
换句话说,您不能使用 Ruby 对 #{} 进行猴子补丁/钩子,但正如 cremno 所建议的,您应该查看 C 部分以通过使用您自己的钩子重新编译 Ruby 来覆盖 #{ } 的默认行为。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句