【问题标题】:Dynamic variable from each method每种方法的动态变量
【发布时间】:2020-12-02 13:59:10
【问题描述】:

我有一个数组,我想迭代并创建动态变量。此外,我想循环它。知道如何实现吗?

代码:

collection = ["s", "g", "l"]

collection.each do |variable_name|
   devan_'#{variable_name}' = ['h1', 'h2', 'h3']
   devan_'#{variable_name}'.each do |s1|
     puts "from #{variable_name} we got #{s1}"
   end
end

异常

 syntax error, unexpected '=', expecting end
   devan_'#{variable_name}' = ['h1', 'h2', 'h3']

【问题讨论】:

  • 你能添加一个输入和预期输出的例子吗?
  • 将数据分配给动态变量对我来说听起来像是一个完美的哈希用例。
  • ...部分原因是,自 Ruby v1.8 以来,无法动态创建局部变量。

标签: ruby each


【解决方案1】:

正如其他评论者所建议的,您可能需要哈希而不是动态变量:

collection = ["s", "g", "l"]

collection.each do |key|
   devan[key] = ['h1', 'h2', 'h3']
   devan[key].each do |s1|
     puts "from #{key} we got #{s1}"
   end
end

使用哈希,您可以“免费”获得一系列易于使用的方法,否则使用动态变量会更加麻烦。例如:

# Add an element to the array for the 's' key:
devan['s'].push 'h4'

# Add an element to the array for each key:
devan.each_key { |k| devan[k].push 'h5' }

# Print array length for each key:
devan.each { |k,v| puts v.length }

【讨论】:

    【解决方案2】:

    从块内部设置动态实例变量

    您尝试执行的元编程类型必须在 Ruby 中与其他一些语言有所不同。在 Ruby 中,您不能简单地将字符串附加到赋值左侧的变量名,然后将其识别为当前命名空间中的有效变量。当涉及范围门时,这会更加成问题。即使它有效,您最终也会得到在当前块之外不存在的块局部变量。

    作为如何解决此语言设计选择的示例,请考虑这种利用Object#instance_variable_set 定义变量并使用Object#instance_variable_get 读取变量的动态方法:

    %w[s g l].map do |ext|
      varname = "@devan_#{ext}"
      instance_variable_set varname, ['h1', 'h2', 'h3']
      puts "#{varname} = #{instance_variable_get varname}"
    end
    
    [@devan_s, @devan_g, @devan_l]
    #=> [["h1", "h2", "h3"], ["h1", "h2", "h3"], ["h1", "h2", "h3"]]
    

    通过使用这种方法来设置或读取实例变量,您可以将字符串插值作为参数传递,而不是作为赋值或方法调用的左侧元素。您只需要使用前导 @ 符号来命名变量。

    通过使用实例变量,您还可以确保在本地块范围之外创建(并继续存在)新变量。如果这不是您真正想要的,请考虑改用Binding#local_variable_set 和Binding#local_variable_get。

    【讨论】:

    • 在我所有多年的经验中,我从未见过这样的情况,当我有一个值数组并动态设置这样的实例变量比散列或数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    相关资源
    最近更新 更多