Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic ruby for temporary variables within a method

Within a method, I am using i and j as temporary variables while calculating other variables. What is an idiomatic way of getting rid of i and j once they are no longer needed? Should I use blocks for this purpose?

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

Background: I'd like to get rid of i and j once they are no longer needed so that they aren't used by any other code in the method. Gives my code less opportunity to be wrong. I don't know the name of the concept - is it "encapsulation"? The closest concepts I can think of are (warning: links to TV Tropes - do not visit while working) Chekhov'sGun or YouHaveOutlivedYourUsefulness.

Another alternative would be to put the code into their own methods, but that may detract from readability.

like image 744
Andrew Grimm Avatar asked Sep 24 '26 04:09

Andrew Grimm


2 Answers

What makes you think splitting the code up into multiple methods will hurt the readability? In my experience, splitting even small or medium sized pieces of code into multiple methods can greatly improve readability.

like image 114
dbyrne Avatar answered Sep 25 '26 18:09

dbyrne


Ruby (like JS) doesn't create a new scope for each block by default (as C++, etc. do). However, in Ruby 1.9, you can try:

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()

See How to make block local variables the default in ruby 1.9?. Any variables that you want to be used outside the block should be defined before-hand (like last_nucleotide_position).

FM is right that a separate method may be more readable.

like image 42
Matthew Flaschen Avatar answered Sep 25 '26 19:09

Matthew Flaschen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!