如何在Ruby中动态访问和分配字符串值作为字符串名
在PHP中,我可以通过设置如何在Ruby中动态访问和分配字符串值作为字符串名,ruby,string,variable-assignment,Ruby,String,Variable Assignment,在PHP中,我可以通过设置$variable\u name=foo和echo$$variable\u name之类的内容来动态访问变量,然后echo将foo的值。但我不清楚如何在Ruby中实现这一点。在PHP中,我可以这样做;在数组中指定变量名并对其进行迭代: # Set string values. $value_one = 'a one'; $value_two = 'and a two'; $value_three = 'and a three'; # Set array of vari
$variable\u name=foo
和echo$$variable\u name
之类的内容来动态访问变量,然后echo
将foo
的值。但我不清楚如何在Ruby中实现这一点。在PHP中,我可以这样做;在数组中指定变量名并对其进行迭代:
# Set string values.
$value_one = 'a one';
$value_two = 'and a two';
$value_three = 'and a three';
# Set array of variable names.
$process_items_array = array('value_one', 'value_two', 'value_three');
# Roll through the values.
foreach ($process_items_array as $value) {
$$value = do_something($$value) . '<br />';
}
# A simple function for example’s sake.
function do_something ($value = null) {
return strtoupper($value);
}
注意我尝试使用,[send][2]
和;我基本上希望有些东西能起作用,但似乎什么都不起作用。我应该做什么呢?您可以通过以下方式来完成:
正如评论中所说,您可能希望将数据存储在散列中。另外,需要动态创建或读取变量的代码闻起来非常糟糕。一种更为ruby的方式(因此没有“危险”的评估)
您可以使用获取当前的绑定
对象,然后使用和获取并设置局部变量:
# Set string values.
value_one = 'a one';
value_two = 'and a two';
value_three = 'and a three';
# Set array of variable names.
process_items_array = ['value_one', 'value_two', 'value_three']
# Roll through the values.
process_items_array.each { |value|
binding.local_variable_set(value.to_sym, do_something(binding.local_variable_get(value).to_sym)
}
# A simple function for example’s sake.
def do_something value
value = value.try(:strip)
value = nil if value.blank?
value.upcase
end
# Show that it works:
p value_one, value_two, value_three
# "A ONE"
# "AND A TWO"
# "AND A THREE"
但是,该代码有点不符合实际:
- 不能同时使用分号和换行符作为表达式分隔符,只能使用一个
- 您可以使用
s来表示变量名,而不是Symbol
sString
- 对于多行边效应块,您将使用
/do
而不是end
/{
}
- 您不会在变量名中声明变量引用的对象类型(例如
)foo\u数组
dou\u something
之前,还必须将其定义上移,否则会出现NoMethodError
为了更容易再现,我删除了对活动\u支持的依赖,这样尝试测试这一点的人就不必安装额外的gem,而复制解决方案甚至不需要它
这将是一个更惯用的代码版本:
# Set string values.
value_one = 'a one'
value_two = 'and a two'
value_three = 'and a three'
# Set array of variable names.
items_to_process = %i[value_one value_two value_three]
# A simple method for example’s sake.
def do_something(value)
value.upcase
end
b = binding
# Roll through the values.
items_to_process.each do |var|
b.local_variable_set(var, do_something(b.local_variable_get(var)))
end
# Show that it works:
p value_one, value_two, value_three
# "A ONE"
# "AND A TWO"
# "AND A THREE"
我知道你使用它的目的,但它似乎不应该在Ruby中使用-可能有一种更健壮的方法,只需稍加重新设计即可。这就是字典和散列图的发明目的-通过另一个(可变)键引用值。@JavaNut13虽然我很欣赏你所说的,事实上,我无法重构我没有创建的整个代码库,因此我必须简单地使用现有的代码库,并尽我所能处理它。如果客户认为重构是值得花时间/精力的,我会考虑走这条路。因此,这个答案在访问字符串数据方面确实有效,但我如何重新分配它呢?我刚刚编辑了我的问题,删除了echo
和put
。我基本上想做eval(value)=做某事eval(value)
。怎么做?Eval只会返回问题中的ruby代码返回的值,我会在一分钟内更新我的答案。你能编辑你的答案,以获得执行此操作所需的实际代码,而不是回答注释吗?@JakeGould done,只是想向你说明Eval是什么does@JakeGould很乐意帮忙,希望你会爱上Ruby=)不幸的是,绑定只在Ruby 2.1中可用,后来我发布了一篇文章,展示了如何为你的方便调用一个方法。“如果你能控制发送给它的数据,一个更加Ruby的方法(因此没有“危险的”eval)eval
是不危险的;在我的例子中,eval
永远不会成为风险,因为数据是隔离/控制的。也就是说,如果您认为local\u variable\u get
比eval
更“危险”,请阅读手册页面,其中明确说明local\u variable\u get
只是一种方便的绑定.eval(“{symbol}”)的方法。6个一个,1/2个一打。
# Set string values.
value_one = 'a one';
value_two = 'and a two';
value_three = 'and a three';
# Set array of variable names.
process_items_array = ['value_one', 'value_two', 'value_three']
# Roll through the values.
process_items_array.each do |variable_name|
# Output value
puts binding.local_variable_get(variable_name.to_sym)
# Reassign variable
binding.local_variable_set(variable_name.to_sym, 'foo')
end
puts value_one, value_two, value_three
# foo
# foo
# foo
# Set string values.
value_one = 'a one';
value_two = 'and a two';
value_three = 'and a three';
# Set array of variable names.
process_items_array = ['value_one', 'value_two', 'value_three']
# Roll through the values.
process_items_array.each { |value|
binding.local_variable_set(value.to_sym, do_something(binding.local_variable_get(value).to_sym)
}
# A simple function for example’s sake.
def do_something value
value = value.try(:strip)
value = nil if value.blank?
value.upcase
end
# Show that it works:
p value_one, value_two, value_three
# "A ONE"
# "AND A TWO"
# "AND A THREE"
# Set string values.
value_one = 'a one'
value_two = 'and a two'
value_three = 'and a three'
# Set array of variable names.
items_to_process = %i[value_one value_two value_three]
# A simple method for example’s sake.
def do_something(value)
value.upcase
end
b = binding
# Roll through the values.
items_to_process.each do |var|
b.local_variable_set(var, do_something(b.local_variable_get(var)))
end
# Show that it works:
p value_one, value_two, value_three
# "A ONE"
# "AND A TWO"
# "AND A THREE"