Question

This is valid:

def prime? n
  (2...n).each {|num| return false if n % num == 0 }
  true
end

This is NOT valid

def prime? n
  (2...n).each {|num| n % num == 0 ? return false : true }
end

Aren't these both saying the same thing? Why does the second example cause a syntax error?


Now why does this next example work in the ternary syntax?

def primes max
  primes_arr = []
  (2...max).map { |num| prime?(num) ? primes_arr << num : next }
  primes_arr
end
Was it helpful?

Solution

That code cause a syntax error because the ruby interpreter don't know, where the arguments for return keyword has end up, the correct example is:

def prime? n
   (2...n).each {|num| n % num == 0 ? ( return false ) : true }
end

Here is the next isn't really required just use boolean logic:

def primes max
   primes_arr = []
   (2...max).map { |num| prime?(num) && primes_arr << num }
   primes_arr
end

If we do some optimization, we can do:

def prime? n
   (2...n).all? {|num| n % num != 0 }
end

def primes max
   (2...max).select {|num| prime?(num) }
end

Next level of optimization shell be this:

def primes max
   (2...max).select {|num| (2...num).all? {|num1| num % num1 != 0 } }
end
primes 7
# => [2, 3, 5] 

OTHER TIPS

Adding parenthesis to explicitly state the way Ruby is interpreting what you have:

(2...n).each { |num| (n % num == 0 ? return false) : true }

We can verify this in that we get the same error message with and without the parenthesis:

SyntaxError: (eval):2: syntax error, unexpected keyword_false, expecting ':'

You can solve this by giving explicit parenthesis to force Ruby to interpret it how you want:

(2...n).each { |num| n % num == 0 ? (return false) : true }

Or you can only return false when the case is met (as you have in your question). Or, better yet, use any? instead:

(2...n).any? { |num| n % num != 0 }

Here's a proper usage of ternary operator (no operator at all :) )

def prime? n
  !(2...n).any? {|num| n % num == 0 }
  # or
  # (2...n).all? {|num| n % num != 0 }
end

(1..10).each do |x|
  puts "prime?(#{x}) \# => #{prime?(x)}"
end
# >> prime?(1) # => true
# >> prime?(2) # => true
# >> prime?(3) # => true
# >> prime?(4) # => false
# >> prime?(5) # => true
# >> prime?(6) # => false
# >> prime?(7) # => true
# >> prime?(8) # => false
# >> prime?(9) # => false
# >> prime?(10) # => false
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top