【问题标题】:Ruby -- use a string as a variable name to define a new variableRuby -- 使用字符串作为变量名来定义一个新变量
【发布时间】:2018-02-10 06:47:12
【问题描述】:

我有一个字符串数组:

names = ['log_index', 'new_index']

我想做的是从名称中创建变量:

names.each { |name| name = [] } # obviously it does not do what I want

这些变量没有在代码的任何地方之前声明。

我该怎么做?

【问题讨论】:

  • 变量名中的字符串是什么意思?
  • index 数组从何而来?为什么不直接通过log_index = []new_index = [] 手动分配变量?你想达到什么目的?

标签: ruby-on-rails arrays ruby string metaprogramming


【解决方案1】:

无法在 Ruby 中动态定义新的局部变量

虽然使用 eval 'x = 2',但在 Ruby 1.8 中是可能的。

您可以使用evalbinding.local_variable_set 更改现有变量。

我会考虑使用hash 来存储值。

【讨论】:

  • 我同意 hash 在这种情况下的心态,即使是像 index.each_with_object(Hash.new {|h,k| h[k] = []}) {|i,obj| obj[i]} 这样简单的事情
【解决方案2】:

ruby中不能动态定义局部变量,但是可以动态定义实例变量:

names = ['log_index', 'new_index']
names.each { |name| instance_variable_set("@#{name}", []) }

这给了你:

@log_index
 => [] 
@new_index
 => [] 

您也可以使用instance_variable_get动态访问实例变量:

names = ['log_index', 'new_index']
names.each { |name| puts instance_variable_get("@#{name}").inspect }

【讨论】:

    【解决方案3】:

    你可以使用这个技巧:

    names.each { |name| eval "def #{name}; []; end"  }
    

    【讨论】:

    • 在这种情况下define_method 似乎比eval 更合适。话虽如此,它总是会返回一个空数组,这似乎不是很有用,因为我认为其目的是在其中存储信息。
    猜你喜欢
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多