r3nrut
r3nrut

Reputation: 1055

Ruby - Calling a method from a loop within another method

Here's the problem...

I have a method that I'm calling to strip out characters and convert strings to floats.

def convert_to_float(currency)
  return currency.gsub(/regex/, "").to_f
end

I have another method that is receiving string values. What I'm wanting to do is iterate those received strings through the convert_to_float method instead of applying the gsub to each line. Here is what I've got... is this even possible with the way I'm doing this?

def verify_amounts(total,subtotal,tax)
  arrayoftotals = [total,subtotal,tax]
  arrayoftotals.each do |convert_to_float|
  end

  ftotal = arrayoftotals[0]
  raise "ftotal must be a Float" unless ftotal.kind_of? Float
end

So far its raising the fault stating that the type is not a float which is telling me that the do each loop isn't converting the values.

Help.

Thanks!!!

Upvotes: 0

Views: 3079

Answers (2)

mu is too short
mu is too short

Reputation: 434665

Sounds like you're looking for map:

arrayoftotals = [total, subtotal, tax].map { |x| convert_to_float(x) }

or, since convert_to_float is a method in the same class as verify_amounts, you could use the Object#method method to write it like this:

arrayoftotals = [total, subtotal, tax].map(&method(:convert_to_float))

For example, this:

class Pancakes
    def convert_to_float(currency)
        currency.gsub(/[^\d.]/, '').to_f
    end

    def verify_amounts(total, subtotal, tax)
        arrayoftotals = [total, subtotal, tax].map(&method(:convert_to_float))
        puts arrayoftotals.inspect
    end
end

Pancakes.new.verify_amounts('where1.0', '2.is0', '3.0house')

will give you [1.0, 2.0, 3.0] on the standard output.

Upvotes: 2

EmFi
EmFi

Reputation: 23450

Upon closer inspection there are two things going wrong here.

  1. Your syntax to pass a method as an iterative function is wrong.

    arrayoftotals.each do |convert_to_float|
    end
    

    Works out to be an empty block where the local variable is called convert_to_float. The syntax you're looking for is:

    arrayoftotals.each (&method (:convert_to_float)) 
    

    This passes a Proc object referring to the method convert_to_float as your block.

  2. You are not updating the values within arrayoftotals. So even if convert_to_float was being called, it wouldn't do anything.

    Either change gsub to gsub! to destructively sanitize your strings in place, or use map! instead of each to replace each element in the array with the results of calling the function on it. map! is a better choice because it means you won't have to adjust every other usage of convert_to_float.

Putting it all together:

def convert_to_float(currency)
  return currency.gsub(/regex/, "").to_f
end

def verify_amounts(total,subtotal,tax)
  arrayoftotals = [total,subtotal,tax]
  arrayoftotals.map! (&method (:convert_to_float)

  ftotal = arrayoftotals[0]
   raise "ftotal must be a Float" unless ftotal.kind_of? Float

end

Upvotes: 1

Related Questions