在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
的情况下构建的。
答案 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