aimen alt
aimen alt

Reputation: 102

why isn't the proc loop through each element of the array(ruby)?

trio = Proc.new do |x|
  tf = true
  puts x
  if tf 
    puts "ai yo"
  end

end

trio.call([1, 2, 3, 4, 5])

output:

1 2 3 4 5 ai yo #its only doing the ai yo part only once when I believe it should do it after every number

but What I am expecting of output is:

1 ai yo 2 ai yo 3 ai yo 4 ai yo 5 ai yo

I still cant wrap my head around why this is happening.

Im trying to get this program to work that i thought would be a cool way to use procs although in this specific problem i dont need to basically:

#The prime factors of 13195 are 5, 7, 13 and 29.
#What is the largest prime factor of the number 600851475143 ?

number = 13195

def factorsAndOptions(num, proc = Proc.new {|x|return x})
  factorsArray = []
  for i in 1..num
    factorsArray.push(i) if num % i == 0
  end
  proc.call(factorsArray)
end

largestPrime = Proc.new do |x|
  prime = true
  for j in 2...x
    if (x % x == 0)
      prime = false
   end
  end
  larger = x if prime && larger > x
  puts larger
  larger
end

factorsAndOptions(number, largestPrime)

Upvotes: 0

Views: 504

Answers (2)

Sinstein
Sinstein

Reputation: 909

As has been mentioned, you do not have any looping block. Your proc - trio is acting on the whole array as one single element.

In your example: x becomes [1, 2, 3, 4, 5] and not individual elements of the array as you are expecting.


To circumvent this you can either loop inside your Proc or create a separate Proc that will loop over the elements of the array and call the first Proc.

Example 1

trio = Proc.new do |arr|
  arr.each do |elem|
    puts elem
    if tf
      puts "ai yo"
    end
  end
end

This assumes that arr is an array

Example 2

trio = Proc.new do |x|
  tf = true
  puts x
  if tf
    puts "ai yo"
  end

end


trio_helper = Proc.new do |x| 
 arr = x.to_a
 arr.each do |elem|
   trio.call(elem)
 end
end

trio_helper.call([1, 2, 3, 4, 5])

This utilizes the original Proc you have written and uses another Proc to iterate over the array and call the first one on each element.

Upvotes: 0

Aaron Breckenridge
Aaron Breckenridge

Reputation: 1819

call won't iterate over arguments. What you've written is, effectively:

puts [1, 2, 3, 4, 5]
puts "ai yo"

If you want to iterate, use each:

[1, 2, 3, 4, 5].each(&trio)

Or:

[1, 2, 3, 4, 5].each { |i| trio.call(i) }

Upvotes: 6

Related Questions