使用克隆时如何摆脱ruby中的重复?

时间:2011-04-05 13:54:23

标签: ruby refactoring

此方法只是更改找到的任何player_id的ID。 Reek讨厌它,但我找不到以有意义的方式重构它的方法。

(1..9).each { |n|
    n = n.to_s
    self.player_ids[n] = self.site_id.clone << "_" << self.player_ids[n].clone if self.player_ids[n]        
}

我是否只需忍受这种重复,因为克隆功能不允许我:

player_id = self.player_ids[n]
player_id = self.site_id.clone << "_" << player_id.clone if player_id

示例输入:

{:player_ids => {"2" => "player_name1", "6" => "player_name4", "9" => "player_name9"}

输出:

{:player_ids => {"2" => "PRE_player_name1", "6" => "PRE_player_name4", "9" => "PRE_player_name9"}

2 个答案:

答案 0 :(得分:1)

以下是两种可能的技术,基于您的示例输入和输出:

site_id = 'PRE'
prefix  = "#{site_id}_"
h = {:player_ids => {"2" => "player_name1", "6" => "player_name4", "9" => "player_name9"}}

# If mutating the original hash is not OK
h2 = h.dup
h2[:player_ids] = Hash[ h[:player_ids].map{ |s,n| [s, n.sub(/^/,prefix)] } ]
p h, h2
#=> {:player_ids=>{"2"=>"player_name1", "6"=>"player_name4", "9"=>"player_name9"}}
#=> {:player_ids=>{"2"=>"PRE_player_name1", "6"=>"PRE_player_name4", "9"=>"PRE_player_name9"}}

# If mutating the original hash is OK
h[:player_ids].each{ |id_string,name| name.sub! /^/, prefix }
p h
#=> {:player_ids=>{"2"=>"PRE_player_name1", "6"=>"PRE_player_name4", "9"=>"PRE_player_name9"}}

如果这不是您想要的,请编辑您的问题的示例输入/输出并发表评论,澄清您的需求。

答案 1 :(得分:1)

仅需要

#clone,因为您在字符串上使用了变异操作(<<)。使用字符串插值可以防止不必要的克隆,并使您的代码更加惯用。

player_ids[n] &&= "#{site_id.clone}_#{player_ids[n]}"

作为奖励,我已删除了您对self的不必要引用,并将其替换为和等号。