How do I get rid of duplication in ruby when using clone?
This method is just changing the id for any player_id that is found. Reek hates it, but I can't find a way to refactor it in a meaningful way.
(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]
}
Do I just have to live with this duplication because the clone function doesn't allow me to:
player_id = self.player_ids[n]
player_id = self.site_id.clone << "_" << player_id.clone if player_id
Sample input:
{:player_ids => {"2" => "player_name1", "6" => "player_name4", "9" => "player_name9"}
output:
{:player_ids => {"2" => "PRE_player_name1", "6" 开发者_如何学Go=> "PRE_player_name4", "9" => "PRE_player_name9"}
Here are two possible techniques, based on your sample input and output:
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"}}
If this is not what you want, please edit your question's sample input/output and post a comment clarifying your needs.
#clone
is only required because you are using mutating operations (<<
) on the string. Using string interpolation prevents the unnecessary clone and also makes your code more idiomatic.
player_ids[n] &&= "#{site_id.clone}_#{player_ids[n]}"
As a bonus, I've removed your unnecessary references to self
and replaced your if with an and-equals.
精彩评论