Fellow Stranger
Fellow Stranger

Reputation: 34013

Manipulate local varible in helper method AND return another value

How would I extract the conditionals below into a method?

I want both to set a new value to the variable AND return the iterated item's value.

my_variable = 0

collection_one.each do |item|
  if item.some_attribute != my_variable 
    my_variable = item.some_attribute
    item.some_attribute
  end
  # do other stuff
end

collection_two.each do |item|
  if item.some_attribute != my_variable 
    my_variable = item.some_attribute
    item.some_attribute
  end
  # do other stuff
end

Upvotes: 0

Views: 25

Answers (2)

shevy
shevy

Reputation: 1000

Answer above has already been provided.

My suggestion is to write methods - inside them you can guarantee the outcome.

If you need a persistent variable you could use an @ivar.

Like, change:

my_variable = 0

to

@my_variable = 0

And everywhere else you have my_variable, replace with @my_variable. Then it should work.

You could also abuse an ARRAY constant to store the results there.

ARRAY_RESULT_VALUES = []

ARRAY_RESULT_VALUES << result_from_first_method
ARRAY_RESULT_VALUES << result_from_second_method

Try to decide which path you want to go first. Of course a $global variable is also possible but not necessary and quite ugly.

You could also try to keep using a local variable but you already discovered the problem there:

"i tried to return [item.some_attribute, my_variable], but the new my_variable value is not persisting to the next time the method is run.. – Numbers 1 hour ago" (By the way, you wrote method, but in the code you showed above you never used def ?)

That makes sense because the local variable, as the name implies, will be only local to the scope/method it was bound to. In your case it exists on the first run, on subsequent runs of the same file it would be re-set to nil.

I think an @ivar would be the best solution really. Then you can store the result in a more persistent variable.

Upvotes: 0

Surya
Surya

Reputation: 15992

Value of my_variable will not persist in the next iteration since it's being overridden inside first each method. For that you can do:

my_variable = 0

collection_one.each_wth_object do |item, obj|
  if item.some_attribute != my_variable 
    obj << [item.some_attribute, my_variable]
    my_variable = item.some_attribute
    item.some_attribute
  end
  # do other stuff
end

my_variable = 0 # define it again

collection_two.each_with_object([]) do |item, obj|
  if item.some_attribute != my_variable 
    obj << [item.some_attribute, my_variable]
    my_variable = item.some_attribute
    item.some_attribute
  end
  # do other stuff
end

here obj will hold the values of different array of array: [[item.some_attribute, my_variable], [...], [..],..] inside each each_with_object.

Upvotes: 1

Related Questions