reZach
reZach

Reputation: 9429

How to access variable using a Ruby method call?

I am new to Ruby and don't know how to access data members within a function (syntax-wise). Here is my question. I have a function that will put values into an array of numbers, from a user given range, that are prime. The function looks like so:

#Search for primes within a range
def find_primes(starting, ending)

    #Make an empty array
    a = []

    for x in starting..ending
        if is_prime(x)
            a << x #Store results in array
        end
    end

    yield
end

The catch is that I must use the yield keyword to call another function to get the data from array 'a'. For example, I need to print out consecutive prime numbers, that are stored in 'a', and I have this code to do this (except I don't know how to get at the values of 'a' from the code below. This is called closure, I believe)

find_primes(0,50) do 

    i = 0

    while i < a.size - 1
        print "[#{a[i]} #{a[i+1]} "
    end
end

This is all very new to me and I can't find a good source on how to do what I am tasked to do. Thank you in advance

Upvotes: 1

Views: 58

Answers (2)

sawa
sawa

Reputation: 168101

You have a whole wrong idea. Using for in Ruby is code smell. This is how you do it if you want the iterator built in:

def find_primes(starting, ending, &pr)
  (starting..ending).select{|x| is_prime(x)}.each(&pr)
end

find_primes(1, 10){|x| puts x}

But the code above lacks flexibility. For flexibility, you should just make it return an array (or an enumerator). Then, you can use different iterators:

def find_primes(starting, ending)
  (starting..ending).select{|x| is_prime(x)}
end

find_primes(1, 10).each{|x| puts x}
find_primes(1, 10).each_cons(2){|x, y| puts "#{x} #{y}"}

Upvotes: 1

Dani&#235;l Knippers
Dani&#235;l Knippers

Reputation: 3055

If you want to return the variable a to the block you should use yield a instead of yield, then you can use find_primes like so:

require 'prime'

def find_primes(from, to)
  yield (from..to).select { |n| Prime.prime? n }
end

find_primes(0, 10) do |primes|
  p primes # => [2, 3, 5, 7]
end

Having said that, you can just use find_primes to return the array like a normal method if you want. You don't have to use yield with blocks. That is:

def find_primes(from, to)
  (from..to).select { |n| Prime.prime? n }
end

primes = find_primes(0,10)
# Do something with primes

Upvotes: 0

Related Questions