如何从外部无法访问字符串插值中的局部变量?

时间:2018-05-24 03:27:12

标签: ruby local-variables string-interpolation

在此代码中:

s = "#{a = 2; b = 3; a * b}" # =>"6"
a # => "2"

局部变量ab是在字符串插值中创建的,并且可以在字符串插值之外到达,因为字符串插值不是块,尽管有花括号。

我想在字符串插值中创建局部变量,这些变量只在那里需要,而不是代码中的其他地方,并且在字符串插值完成后应该删除它以最小化副作用和潜在的变量冲突。

我试图创建一个代码块来实现变量的局部性,但没有成功:

s = "#{{a = 2; b = 3; a * b}}"

do ... end相同。

s = "#{do a = 2; b = 3; a * b; end}"

3 个答案:

答案 0 :(得分:3)

出于好奇。以下代码不会删除局部变量,但它会有效地取消设置其值,因此在此之后调用a(或b)将返回nil

%Q|#{
  a = 2
  b = 3
  (a * b).tap do 
    binding.local_variable_set(:a, nil)
    binding.local_variable_set(:b, nil)
  end
}|

之后的方法会提升NameError: undefined local variable or method 'a' ...而不是在这些陈述之后访问a

"#{->() { a = 2; b = 3; a * b }.()}"

# or, credits to @engineersmnky
"#{->(a = 2, b = 3) { a * b }.()}"
"#{->(a, b) { a * b }.(2, 3)}"

此外:

"#{instance_eval { a = 2; b = 3; a * b }}"

答案 1 :(得分:1)

这是我的尝试:

> s = "#{def yielder; yield; end; yielder do a=2; b=3; a*b; end;}"
#=> "6" 

> a
#=> NameError: undefined local variable or method `a' for main:Object
> b
#=> NameError: undefined local variable or method `b' for main:Object

块通常使用定义块时存在的绑定,除非现有绑定与块变量冲突并且使用块变量。可以在块中定义其他本地绑定,并且当块执行完毕时,这些绑定将丢失。

答案 2 :(得分:-1)

使用新的Ruby 2.5 yield_self featurette的方法

"#{ 2.yield_self{|a| 3.yield_self{|b| a*b}} }"