每个方法的动态变量

Dynamic variable from each method

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

代码:

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 中的执行方式与其他一些语言有所不同。在 Ruby 中,您不能简单地将字符串附加到赋值左侧的变量名,并将其识别为当前名称空间中的有效变量。当涉及到作用域门时,问题就更大了;即使它有效,您最终也会得到 block-local 个在当前块之外不存在的变量。

作为如何解决此语言设计选择的示例,请考虑利用 Object#instance_variable_set to define the variable, and 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"]]

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

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

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

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 }