在Ruby中为插值变量分配插值

时间:2014-08-14 21:57:20

标签: ruby

我在方法中有这个:

def create_data_arrays
    @local_result_hash.each do |job|
        @jobIds << job["jobId"]
        @employerNames << job["employerName"]
        @jobTitles << job["jobTitle"]
        @minimumSalarys << job["minimumSalary"]
        @maximumSalarys << job["maximumSalary"]
        @expirationDates << job["expirationDate"]
        @jobDescriptions << job["jobDescription"]
   end
end

这是在主要课程中:

@jobIds = []
@employerNames = []
@jobTitles = []
@minimumSalarys = []
@maximumSalarys = []
@expirationDates = []
@jobDescriptions = []

我想重构该方法,因此我创建了以下数组:

@api_parameters = ["jobId", "employerName", "jobTitle", "minimumSalary", "maximumSalary", "expirationDate", "jobDescription"]

重构方法为:

def create_data_arrays
    @local_result_hash.each do |job|
        @api_parameters.each do |parameter|
            "@#{parameter}" << job[parameter]
        end
    end
end

查询哈希工作正常但"@#{parameter}"不起作用。建议?我在疯狂吗?

2 个答案:

答案 0 :(得分:1)

如果@local_result_hash实际上是一个哈希数组,正如我所料,以下将是一种类似Ruby的方法来创建实例变量。我在缩短变量和键的名称以及删除一些键值对方面采取了一些自由,但没有改变问题的本质。

请注意,您不需要初始化实例变量(例如,没有@jobIds = []; @employerNames = []等),并且您不需要数组@api_parameters。如果添加,删除或重命名属性,这将使维护代码变得更容易。

<强>代码

  def map_to_instance_vars(local_results)    
    local_results.first
                 .keys
                 .zip(local_results.map(&:values).transpose)
                 .each { |name,val| instance_variable_set("@#{ name }", val) }
  end

示例

  h1 = { "jobID"=>123, "title"=>"CEO", "description"=>"The big boss" }
  h2 = { "jobID"=>456, "title"=>"Supervisor", "description"=>"Push paper" }
  h3 = { "jobID"=>789, "title"=>"Flunkie", "description"=>"Do mindless work" }
  local_results = [h1, h2, h3]

  map_to_instance_vars(local_results)
  @jobID
    #=> [123, 456, 789]
  @title
    #=> ["CEO", "Supervisor", "Flunkie"]
  @description
    #=> ["The big boss", "Push paper", "Do mindless work"]

<强>解释

local_results如上例所示。首先跳到Enumerable#zip的论点:

a = local_results.map(&:values)
  #=> [[123, "CEO", "The big boss"],
  #    [456, "Supervisor", "Push paper"],
  #    [789, "Flunkie", "Do mindless work"]]
b = a.transpose
  #=>  [[123, 456, 789],
  #     ["CEO", "Supervisor", "Flunkie"],
  #     ["The big boss", "Push paper", "Do mindless work"]]

现在创建将zip发送到的对象:

keys = local_results.first.keys
  #=> ["jobID", "title", "description"]

并将带有参数keys的{​​{1}}发送给它:

b

最后,使用Object#instance_variable_setc = keys.zip(b) #=> [["jobID", [123, 456, 789]], # ["title", ["CEO", "Supervisor", "Flunkie"]], # ["description", ["The big boss", "Push paper", "Do mindless work"]]] 的每个元素创建一个实例变量:

c

答案 1 :(得分:0)

寻找instance_variable_get

def create_data_arrays
  @local_result_hash.each do |job|
    @api_parameters.each do |parameter|
      instance_variable_get("@#{parameter}s") << job[parameter]
    end
  end
end

另见:apidock.com/ruby/Object/instance_variable_get