如何在Ruby中进行用户输入的字符串模板化?

如何在Ruby中进行用户输入的字符串模板化?,ruby,Ruby,我知道像这样写作 a=23 p "the value of a is #{a}" 它将打印:a的值为23 但是现在我实际接收到这个字符串作为一个参数,比如 def evaluate string a=23 puts string end 调用方法将该字符串作为参数传递 evaluate "the value of a is #{a}" 有没有办法在方法中计算这个字符串放置字符串必须插入值a=23 编辑: 我必须从Excel中读取并执行程序 在

我知道像这样写作

a=23
p "the value of a is #{a}"
它将打印:
a的值为23

但是现在我实际接收到这个字符串作为一个参数,比如

def evaluate string
  a=23
  puts string
end
调用方法将该字符串作为参数传递

evaluate "the value of a is #{a}"
有没有办法在方法中计算这个字符串<代码>放置字符串必须插入值a=23

编辑:

我必须从Excel中读取并执行程序

在第一行,

Excel条目是

"id=something" setvalue a
所以现在相应的程序将从locator id=something读取值,并将其设置到实例变量@a中

用户的下一个excel条目是

"the value of a is 23"  compare "the value of a is #{a}"

现在,程序将读取“a的值是23”和“a的值是#{a}”进行比较,但在进行比较之前,它必须替换值a。这就是我想要的。我希望现在我的问题非常清楚。

您可以制作一个块,然后计算字符串:

def evaluate &block
  a=23
  block.call(a)
end

evaluate { |a| "the value of a is #{a}" } #=> "the value of a is 23"

这是一件非常奇怪的事情,你正试图这样做。当您有某种带有占位符的模式时,您可以执行以下操作:

def evaluate(string)
  a=23
  format string, a: a
end

evaluate "the value of a is %{a}"

带有
{..}
的字符串插值并不适用于您描述的情况,因为值是在构造字符串时计算的,而不是以后。您可以进行一些regexp匹配,并将
{..}
替换为
%{..}
作为解决方法。

对于ruby,您可以更改Excel中字符串的“格式”,而不是使用“经典”格式

a = 23
s = 'the value of a is %s'

def evaluate(text, value)
  puts text % value
end
您可以使用不同的格式键,例如,
%d
用于整数,
%f
用于浮点数

可以使用命名参数

dynamic_text = 'the value of the %<product_name>s is %<product_price>0.2f'

def evaluate(text, args)
  puts text % args
end

name = "Product"
price = 78.99
evaluate dynamic_text, product_name: name, product_price: price
有几种方法:

“代码”动态 使用lambdas进行惰性评估:

def评估(str_模板)
a=23
str_模板调用(a)
结束
用户输入=获取
my_lambda=lambda do|str|
用户输入大小>10?“动态1{str}”:“动态2{str}”
结束
评估(我的lambda)
#=>“动态1/2 23”
这是“代码动态”,但不是“输入动态”,即您无法从用户处接收字符串模板

“输入”动态1 ERB模板:

需要“erb”
用户\u输入\u erb=get
将用户_input_erb#“Hello”
name=获取#也可以是用户输入,例如“World”
新的(用户输入)。结果
#=>“你好,世界”
请注意,通常,从用户处获取字符串模板并对其进行评估是一个潜在的安全漏洞。如果用户输入有可能是对抗性的,那么您需要看看是否可以找到一个“保证对所有用户输入都安全”的字符串模板库

“输入”动态2
user\u input\u template=get
将用户_输入_模板#“Hello%s”
name=获取#也可以是用户输入,例如“World”
用户输入模板%name
#=>“你好,世界”
“输入”动态3 真的很危险,但是:

user_input_ruby_code = gets
puts user_input_ruby_code # '"Hello #{name}"'

name = gets # also user input, e.g. "World"

eval user_input_ruby_code # DANGER
# => "Hello World"

如果之前没有定义
a
,则不能接收到
“a的值为#{a}”
,因为这会引发NameError异常。你查过了吗?我可以把它作为字符串接收。我正在从Excel中读取字符串并在程序中执行它,因此我接收了<代码>值为“{”{ }} /CODE作为字符串,因此它不会抛出任何错误。FIY,如果您想做到这一点,则必须执行用户输入代码,这将引入一个注入攻击向量。更多信息,请参见我的答案。@Kache我现在在我的问题中已经详细介绍了它,你能参考它吗?我不能提供任何未涵盖的建议。不!这个字符串
a的值是{a}
是动态的,例如,下次我可能会收到类似于
计划{a}发出的
内核{code>格式
允许提供比字符串实际拥有的更多的插值参数,例如
格式“a的值是%{b}”,a:'23,b:42
。我很难理解您试图实现的目标。如果只有一个变量,或者参数的顺序与字符串中出现的顺序相同,那么就完全可以了。我是说
“blah blah{str}”
是动态的!那它是怎么工作的呢?是的,它是代码动态的~您是否希望从用户处接收字符串模板?动态的方法不止一种,你应该澄清。用户首先设置a的值,然后用户将在Excel中给出输入字符串,如
a的值为#{a}
。更新以添加“输入”动态示例。注意:此版本要求信任用户输入。现在更新了问题。用户将在Excel中给出此字符串“a的值为%s”
,并且他们将从Excel中设置a的值。我已经编写了一个代码,通过使用
实例变量集设置a的值,但是现在使用您的代码,他必须在字符串中给出变量名。但你的代码不是这样的。用户不需要给变量名,变量名可以是任何东西。使用命名参数时,您只需将给定给方法
evaluate
的哈希值与动态字符串中使用的名称进行匹配。@Rajagopalan,如果用户要在excel中设置值,您只需将excel中的值“转换”为哈希值{value\u name:name},并将其传递给
evaluate
methodNope。很难向你解释。但是谢谢你的尝试@Rajagopalan,你能展示一下你是如何从excel中获取值的吗?因为,如果用户在excel中设置值,他们需要以某种方式命名这些值。如果他们为值输入了一个名称,那么您可以将其转换为散列。如果他们输入的值没有名称,那么他们可能会使用值的顺序来识别哪个值是什么。在这种情况下,您可以将值转换为一个数组,并将其传递给求值方法,它就可以工作了
user_input_ruby_code = gets
puts user_input_ruby_code # '"Hello #{name}"'

name = gets # also user input, e.g. "World"

eval user_input_ruby_code # DANGER
# => "Hello World"