>> string = '#{var}'
=> "\#{var}"
>> proc = Proc.new { |var| string }
=> #<Proc:0xb717a8c4@(pry):6>
>> proc.call(123)
=> "\#{var}"
这并不是我想要的。在string
周围放双引号会导致明显的undefined local variable
错误。
>> string = '#{var}'
=> "\#{var}"
>> proc = Proc.new { |var| string }
=> #<Proc:0xb717a8c4@(pry):6>
>> proc.call(123)
=> "\#{var}"
这并不是我想要的。在string
周围放双引号会导致明显的undefined local variable
错误。
Proc
的被接受答案,我认为它过于复杂了。 在Ruby 1.8.7中,您可以使用以下%
语法:"This is a %s verb, %s" % ["nice", "woaaaah"]
如果至少使用 ruby 1.9.x(或带有 i18n 的 ruby 1.8.7),则有一个更清晰的替代方案:
my_template = "This is a %{adjective} verb, %{super}!"
my_template % { adjective: "nice", super: "woah" }
=> "This is a nice verb, woah!"
string = '%s'
proc = Proc.new { |var| string % var }
proc.call(123)
# => "123"
这是一种非常可靠的方法,因为任何支持 .to_s
方法的内容都可以使用,且如果它包含可执行代码也不会导致宇宙坍塌。
String#%
也支持使用 Hash 作为参数的命名参数,这使得它非常接近本地字符串插值的功能。 - Mladen Jablanović它可以通过eval进行工作:
proc = Proc.new { |var| eval(%Q{"#{string}"}) }
%q[]
来表达,例如:%q["#{string}"]
,以避免所有可怕的转义。 - tadmaneval
可以用。但是也许还有其他方法? - Paweł Gościckieval(string)
。这很可怕、很危险。我曾经在ActiveRecord的自定义查找SQL中看到过这种用法,它总是让我感到非常糟糕。大致上来说,你可以使用gsub
函数将模式替换为%s
,然后进行插值操作,而不必采取核心选项。 - tadman%Q
会进行插值,所以如果你愿意的话,可以使用 %Q{#{string}}
。 - mu is too shortrails_root = "whatever" # Not variant for the string
rails_env_prompt = "whatever" #not variant for the string
spec = Proc.new { |tail_char|
Proc.new {|obj, nest_level, *|
"#{rails_root} #{rails_env_prompt} #{obj}:#{nest_level}#{tail_char} "
}
}
Pry.config.prompt = [ spec.call(">"), spec.call("*") ]
Pry.config.prompt[0].call("My obj", "My Nest Level")
# result: "whatever whatever My obj:My Nest Level> "
你必须在Proc之外定义插值字符串吗?
proc = Proc.new { |var| "#{var}" }
proc.call(123) # "123"
x=1
s="#{x}"
$ ruby --dump=insns <<EXAMPLE
x=1
s="#{x}"
EXAMPLE
== disasm: #<ISeq:<main>@-:1 (1,0)-(2,8)> (catch: FALSE)
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] x@0 [ 1] s@1
0000 putobject_INT2FIX_1_ ( 1)[Li]
0001 setlocal_WC_0 x@0
0003 putobject "" ( 2)[Li]
0005 getlocal_WC_0 x@0
0007 dup
0008 checktype T_STRING
0010 branchif 17
0012 dup
0013 opt_send_without_block <callinfo!mid:to_s, argc:0, FCALL|ARGS_SIMPLE>, <callcache>
0016 tostring
0017 concatstrings 2
0019 dup
0020 setlocal_WC_0 s@1
0022 leave
x=1
s="%{foo}" % {foo: x}
每次调用都会将一个格式字符串推入堆栈(指令0003),并调用String#%
(指令0007)以重新解析它,从而触发与Kernel::sprintf文档中描述的相同的格式解析代码。
$ ruby --dump=insns <<EXAMPLE
> x=1
> s="%{foo}" % {foo: x}
> EXAMPLE
== disasm: #<ISeq:<main>@-:1 (1,0)-(2,21)> (catch: FALSE)
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] x@0 [ 1] s@1
0000 putobject_INT2FIX_1_ ( 1)[Li]
0001 setlocal_WC_0 x@0
0003 putstring "%{foo}" ( 2)[Li]
0005 getlocal_WC_0 x@0
0007 opt_send_without_block <callinfo!mid:%, argc:1, kw:[foo], KWARG>, <callcache>
0010 dup
0011 setlocal_WC_0 s@1
0013 leave