# Guess a number, any number, between 1 and 10

I am learning Ruby and would like to know how I am doing as far as writing the actual code.

Please keep in mind that this is my first Ruby script program, but I am trying to learn ruby in a very short period of time.

I would like to know about nitpicks in the language that every Ruby writer should now, nuances in syntax, and other Ruby specific ... things.

$randomNumber = rand(10) + 1 def guessRandomNumber puts "Guess a number between 1 and 10" guess = gets if Integer(guess) ==$randomNumber
puts "Right on, good guess"
elsif Integer(guess) < $randomNumber puts "too low" puts "please, guess again" guessRandomNumber elsif Integer(guess) >$randomNumber
puts "too high"
guessRandomNumber
else
puts "is that even a number? please, guess again"
guessRandomNumber
end
end

guessRandomNumber

puts "bye"
gets


Don't use global variables(like $bar). It is always bad practice because you can mutate the global variable from anywhere. The alternative is: RANDOM_NUMBER = rand(1..10), notice that you can pass range as an argument of rand. rand(10) + 1 can return 11 so it isn't correct. ### Style Huge percentage of the Ruby community follow the style guide and this is the most popular one Ruby style guide. Style issues: • Use snake case for the names of methods and variables. • Use double quotes only if you use interpolation or special symbols like \n. ### About the implementation IMO will be more readable like this: def guess_random_number puts 'Guess a number between 1 and 10' random_number = rand(1..10) while random_number != (guess_number = gets.to_i) if guess_number < random_number puts "too low \nplease, guess again" else puts "too high \nplease, guess again" end end puts "Right on, good guess \nbye" end guess_random_number  You see there is no need to expose the variable in the global scope. • How will that work of the user enters letters instead of numbers? – Malachi May 21 '16 at 17:57 • @Malachi gets.to_i will return 0 if the input is not a number (as I already explained in my answer) – janos May 21 '16 at 18:37 • You forgot to mention that while loops are frowned upon. – 13aal May 22 '16 at 1:17 • @13aal - This is the most readable solution that I can think of, recursion isn't that intuitive. But I don't really like the iterative style of programming. I will be happy if a see more functional solution. – Kamen Kanev May 22 '16 at 15:34 • @13aal Still interested in your version if you had time to do it. – Marc-Andre Jun 16 '16 at 15:18 Disclaimer: I don't really know Ruby. Instead of converting guess to Integer in every if/elseif, it would be better to do that once: guess = Integer(gets)  In any case, Integer(somestring) works only if somestring is actually an integer, and your script currently doesn't handle that case. (The else statement is unreachable.) To correct that, you could add proper input validation. Or, alternatively, you could use the to_i function, which tries to interpret the leading characters as an integer, and if it fails, returns 0 instead. guess = gets.to_i  With this change, and the unreachable else case removed, the program becomes: $randomNumber = rand(10) + 1

def guessRandomNumber
puts "Guess a number between 1 and 10"
guess = gets.to_i
if guess == $randomNumber puts "Right on, good guess" return end if guess <$randomNumber
puts "too low"
else
puts "too high"
end
guessRandomNumber
end

guessRandomNumber

puts "bye"


This could be still better. Reading user input repeatedly until some condition is a common pattern. Using recursion for the repeated prompt is usually considered bad form, as it can lead to excessive deep call stacks until overflow. Although in this particular example that's unrealistic to happen, for the sake of good habits, I recommend to rewrite this in an iterative way.

You could put multiple different methods to obtain your resolution, for example, a prompt method that requires input to ask the question. A check_num method to check the numbers that requires arguments pertaining to the numbers, a restart method that will be called if the number is incorrect, and a begin_game method that will be called to start the game. This uses recursion and yes, it can get a little tricky when you use recursion. It is possible that it will eventually cause a stack overflow error however with this simple little program, it isn't that likely. This is also a more OOP way of writing it, which is what Ruby is all about. Here's my take on it:

RAND_NUM = rand(1..10) #<= Turn the number into a constant

def prompt(input) #<= Prompt method that requires an argument
print input
gets.chomp.to_i #<= Turn the output into a Integer
end

def check_num(num, num2) #<= Check the number against another number
if num != num2 #<= If the number does not equal the other number
restart
else
puts 'Good guess, later..'
exit #<= Exit if the numbers match
end
end

def restart #<= Restart method, basically the same as the begin_game, but causes recursion
num = prompt('Enter a number between 1 - 10: ')
check_num(RAND_NUM, num)
end

def begin_game
num = prompt('Enter a number between 1 - 10: ')
check_num(RAND_NUM, num)
end

begin_game


Now when this is run:

Enter a number between 1 - 10: 1
Good guess, later..

Enter a number between 1 - 10: 1
Enter a number between 1 - 10: 2
Enter a number between 1 - 10: 3
Good guess, later..

Enter a number between 1 - 10: 1
Enter a number between 1 - 10: 2
Enter a number between 1 - 10: 3
Enter a number between 1 - 10: 4
Enter a number between 1 - 10: 5
Enter a number between 1 - 10: 6
Enter a number between 1 - 10: 7
Enter a number between 1 - 10: 8
Enter a number between 1 - 10: 9
Good guess, later..