Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Ruby中动态访问和分配字符串值作为字符串名_Ruby_String_Variable Assignment - Fatal编程技术网

如何在Ruby中动态访问和分配字符串值作为字符串名

如何在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

在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 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"
但是,该代码有点不符合实际:

  • 不能同时使用分号和换行符作为表达式分隔符,只能使用一个
  • 您可以使用
    Symbol
    s来表示变量名,而不是
    String
    s
  • 对于多行边效应块,您将使用
    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"