2010-05-20 78 views
3

在一个方法中,我使用ij作为临时变量,同时计算其他变量。一旦不再需要它,摆脱ij的习惯用法是什么?我应该为此使用块吗?方法内临时变量的习惯ruby

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 

背景:我想摆脱ij一旦他们不再需要,使他们不使用该方法的任何其他代码。让我的代码更少出错的机会。我不知道这个概念的名称 - 是“封装”吗?我能想到的最接近的概念是(警告:链接到电视节目 - 不要在工作时访问)Chekhov'sGunYouHaveOutlivedYourUsefulness

另一种替代方法是将代码放入自己的方法中,但这可能会降低可读性。

回答

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是正确的,一个单独的方法可能更具可读性。

4

是什么让你认为把代码分解成多个方法会损害可读性?根据我的经验,即使将中小尺寸的代码拆分为多个方法也可以大大提高可读性。

2

我认为你要找的术语是可变范围 - 换句话说,你正在寻找方法来限制ij的范围。但你不必担心这一点。目前的问题需要创建单独的方法 - 无论范围考虑。

这样可以提高可读性,因为它可以让读者从高层开始编码,然后根据需要深入钻取。它也将提高可测性,因为你的小方法只能做一件事

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... 
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'