Ruby 中的 DRY - 可以重复一行代码吗?
DRY in Ruby - Is it okay to repeat a line of code?
我是编程新手 ruby。我正在使用一种方法来识别某人的秘密圣诞老人是谁。该方法采用字符串和整数参数(名字或 ID)。我对 String 和 Integer 参数有不同的代码。这导致为不同的参数重复相同的代码行 (secret = PERSONS[person[:santa]-1]).
我的问题有两个:
这种重复是否违反DRY原则?还有其他方法可以避免重复吗?
看到我在迭代器外初始化了 local_variable secret 并使用迭代器传递给那个变量。这是最有效的方法吗?我可以只 return 来自迭代器的值而不初始化局部变量吗?
我的代码如下。另外,我附上了我 运行 代码的数据散列样本(PERSONS)。
def who_is_secret_santa(first_name)
secret = nil
PERSONS.each do |person|
if first_name.is_a? String
if person[:first_name] == first_name
secret = PERSONS[person[:santa]-1]
end
elsif first_name.is_a? Integer
if person[:id] == first_name
secret = PERSONS[person[:santa]-1]
end
else
puts "Bad argument"
end
end
puts "#{first_name}'s Secret Santa " + (secret ? "is #{secret[:first_name]}" : "not found")
end
[{:id=>1,
:first_name=>"Luke",
:last_name=>"Skywalker",
:email=>"<luke@theforce.net>",
:santa=>4},
{:id=>2,
:first_name=>"Leia",
:last_name=>"Skywalker",
:email=>"<leia@therebellion.org>",
:santa=>7},
{:id=>3,
:first_name=>"Toula",
:last_name=>"Portokalos",
:email=>"<toula@manhunter.org>",
:santa=>5},
{:id=>4,
:first_name=>"Gus",
:last_name=>"Portokalos",
:email=>"<gus@weareallfruit.net>",
:santa=>2},
{:id=>5,
:first_name=>"Bruce",
:last_name=>"Wayne",
:email=>"<bruce@imbatman.com>",
:santa=>3},
{:id=>6,
:first_name=>"Virgil",
:last_name=>"Brigman",
:email=>"<virgil@rigworkersunion.org>",
:santa=>1},
{:id=>7,
:first_name=>"Lindsey",
:last_name=>"Brigman",
:email=>"<lindsey@iseealiens.net>",
:santa=>6}]
在这种情况下,有一种方法可以避免重复,方法是首先检查 "bad argument",然后从数组中选择正确的人。
对于你的第二个问题,你可能正在寻找 select 迭代器而不是 each。它将 return 数组中使传递给它的块中的条件为真的所有元素。
下面是一些代码。 p 将代表 first_name 被传递给方法的人。
def who_is_secret_santa(first_name)
if ! ((first_name.is_a? String) || (first_name.is_a? Integer))
puts "Bad argument"
else
p = (PERSONS.select do |person| person[:first_name] == first_name || person[:id] == first_name end)[0]
puts "#{first_name}'s Secret Santa " + (p ? "is #{PERSONS[p[:santa]-1][:first_name]}" : "not found")
end
end
我是编程新手 ruby。我正在使用一种方法来识别某人的秘密圣诞老人是谁。该方法采用字符串和整数参数(名字或 ID)。我对 String 和 Integer 参数有不同的代码。这导致为不同的参数重复相同的代码行 (secret = PERSONS[person[:santa]-1]).
我的问题有两个:
这种重复是否违反DRY原则?还有其他方法可以避免重复吗?
看到我在迭代器外初始化了 local_variable secret 并使用迭代器传递给那个变量。这是最有效的方法吗?我可以只 return 来自迭代器的值而不初始化局部变量吗?
我的代码如下。另外,我附上了我 运行 代码的数据散列样本(PERSONS)。
def who_is_secret_santa(first_name)
secret = nil
PERSONS.each do |person|
if first_name.is_a? String
if person[:first_name] == first_name
secret = PERSONS[person[:santa]-1]
end
elsif first_name.is_a? Integer
if person[:id] == first_name
secret = PERSONS[person[:santa]-1]
end
else
puts "Bad argument"
end
end
puts "#{first_name}'s Secret Santa " + (secret ? "is #{secret[:first_name]}" : "not found")
end
[{:id=>1,
:first_name=>"Luke",
:last_name=>"Skywalker",
:email=>"<luke@theforce.net>",
:santa=>4},
{:id=>2,
:first_name=>"Leia",
:last_name=>"Skywalker",
:email=>"<leia@therebellion.org>",
:santa=>7},
{:id=>3,
:first_name=>"Toula",
:last_name=>"Portokalos",
:email=>"<toula@manhunter.org>",
:santa=>5},
{:id=>4,
:first_name=>"Gus",
:last_name=>"Portokalos",
:email=>"<gus@weareallfruit.net>",
:santa=>2},
{:id=>5,
:first_name=>"Bruce",
:last_name=>"Wayne",
:email=>"<bruce@imbatman.com>",
:santa=>3},
{:id=>6,
:first_name=>"Virgil",
:last_name=>"Brigman",
:email=>"<virgil@rigworkersunion.org>",
:santa=>1},
{:id=>7,
:first_name=>"Lindsey",
:last_name=>"Brigman",
:email=>"<lindsey@iseealiens.net>",
:santa=>6}]
在这种情况下,有一种方法可以避免重复,方法是首先检查 "bad argument",然后从数组中选择正确的人。
对于你的第二个问题,你可能正在寻找 select 迭代器而不是 each。它将 return 数组中使传递给它的块中的条件为真的所有元素。
下面是一些代码。 p 将代表 first_name 被传递给方法的人。
def who_is_secret_santa(first_name)
if ! ((first_name.is_a? String) || (first_name.is_a? Integer))
puts "Bad argument"
else
p = (PERSONS.select do |person| person[:first_name] == first_name || person[:id] == first_name end)[0]
puts "#{first_name}'s Secret Santa " + (p ? "is #{PERSONS[p[:santa]-1][:first_name]}" : "not found")
end
end