在方法中,我在计算其他变量时使用i
和j
作为临时变量。一旦不再需要它们,摆脱i
和j
的惯用方法是什么?我应该为此目的使用块吗?
i = positions.first
while nucleotide_at_position(i-1) == nucleotide_at_position(i)
raise "Assumption violated" if i == 1
i -= 1
end
first_nucleotide_position = i
j = positions.last
while nucleotide_at_position(j+1) == nucleotide_at_position(j)
raise "Assumption violated" if j == sequence.length
j += 1
end
last_nucleotide_position = j
背景:我想在不再需要i
和j
之后将其删除,以免其他任何代码使用它们方法。使我的代码减少出错的机会。我不知道这个概念的名称 - 它是“封装”吗?我能想到的最接近的概念是(警告:电视特洛伊的链接 - 工作时不要访问)Chekhov'sGun或YouHaveOutlivedYourUsefulness。
另一种选择是将代码放入他们自己的方法中,但这可能会降低可读性。
答案 0 :(得分:4)
是什么让您认为将代码拆分为多种方法会损害可读性?根据我的经验,即使将中小型代码分割成多种方法也可以大大提高可读性。
答案 1 :(得分:2)
我认为您正在寻找的术语是可变范围 - 换句话说,您正在寻找限制i
和j
范围的方法。但你不必担心这一点。手头的问题需要创建单独的方法 - 无论考虑范围如何。
这将提高可读性,因为它将允许读者从高级别开始编写代码,然后根据需要深入钻孔。它还将提高可测试性,因为您的小方法将完全一件事。
def calc_first_nucleotide_position(po)
i = po.first
while nucleotide_at_position(i-1) == nucleotide_at_position(i)
raise "Assumption violated" if i == 1
i -= 1
end
i
end
# etc...
first_nucleotide_position = calc_first_nucleotide_position(positions)
last_nucleotide_position = calc_last_nucleotide_position(positions)
# etc...
答案 2 :(得分:2)
Ruby(如JS)默认情况下不会为每个块创建新的作用域(如C ++等)。但是,在Ruby 1.9中,您可以尝试:
last_nucleotide_position = nil
proc { |;i, j|
i = positions.first
while nucleotide_at_position(i-1) == nucleotide_at_position(i)
raise "Assumption violated" if i == 1
i -= 1
end
first_nucleotide_position = i
j = positions.last
while nucleotide_at_position(j+1) == nucleotide_at_position(j)
raise "Assumption violated" if j == sequence.length
j += 1
end
last_nucleotide_position = j
}.call()
见How to make block local variables the default in ruby 1.9?。您希望在块外使用的任何变量都应该在前面定义(如last_nucleotide_position)。
FM是正确的,单独的方法可能更具可读性。
答案 3 :(得分:1)
您正在寻找与Lisp的let
特殊运算符相当的Ruby。 Ruby不支持开箱即用,但你可以很容易地破解它,结果语法是这样的:
x = 10
scope { |x|
x = 30
}
puts x #=> 10
请参阅:http://banisterfiend.wordpress.com/2010/01/07/controlling-object-scope-in-ruby-1-9/
答案 4 :(得分:1)
如果你想要的只是让新变量不会溢出到程序的其余部分,你可以使用1.times
将代码包装在一个块中。当您关闭块时,您在块内创建的任何新变量都将被销毁。请记住,一旦块关闭,您对预先存在的变量所做的任何更改都将保留。
y = 20
1.times do
# put your code in here
i = 1
puts x = y # => 20, because y is available from outside the block
y = 'new value' # We can change the value of y but our changes will
# propagate to outside the block since y was defined before we opened
# the block.
end
defined? i # => nil, i is lost when you close the block
defined? x # => nil, x is also local to the block
puts y # => 'new value'