如何在Ruby中跟踪字符串创建?

时间:2010-12-06 23:44:54

标签: ruby tracing

this answer to a separate question,我说如果你这样做

name = "Rohit " "Sharma"

你没有创建两个String个对象,其内容"Rohit ""Sharma"组合起来创建一个内容为"Rohit Sharma"的新String对象,但你只是创建一个String对象以开始。

但它只是一本书告诉我,而不是手动验证它。

您如何记录字符串的创建?

我尝试使用

set_trace_func proc { |event, file, line, id, binding, classname|
  printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}

string = "Insert content here"

但只有

c-return -:3  set_trace_func   Kernel
    line -:5

“编程Ruby 1.9”(Pickaxe)说修改Class#new对字符串不起作用,因为它们是在不使用new的情况下构建的。

2 个答案:

答案 0 :(得分:3)

您无法记录此内容,因为此连接不会在运行时发生。它发生在解析时。

换句话说:无论你编写什么代码来记录这个,连接都会在你的代码运行之前发生。

换句话说:您相信只有一个字符串对象的创建方式与您相信42仅创建一个值Fixnum的{​​{1}}对象的方式相同,而不是42 {1}}值为Fixnum的对象:ISO Ruby语言规范说明了这一点,并且每个现有Ruby实现的源代码都是这样说的,而且每本Ruby书都写过这样说。

答案 1 :(得分:0)

这不会跟踪字符串创建,但以下建议在创建任何字符串对象之前进行连接:

以下(我在Pickaxe中,在“幕后花絮:Ruby VM”一节中读到这一点)在YARV中工作 - 我认为它不适用于ruby的任何其他实现:

irb(main):003:0> uncompiled_code = 'name = "Rohit " "Sharma"'
=> "name = \"Rohit \" \"Sharma\""
irb(main):004:0> code = RubyVM::InstructionSequence.compile(uncompiled_code)
=> <RubyVM::InstructionSequence:<compiled>@<compiled>>
irb(main):005:0> puts code.disassemble
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] name
0000 trace            1                                               (   1)
0002 putstring        "Rohit Sharma"
0004 dup
0005 setlocal         name
0007 leave
=> nil