Here is some code:
print "What is your name?"
userinput = gets.chomp.downcase!
if userinput.include? "s"
print "I found it"
else
print "found nothing"
end
It gives the error: undefined method `include?' for nil:NilClass
but when I change it to:
print "What is your name?"
userinput = gets.chomp
userinput.downcase!
if userinput.include? "s"
print "I found it"
else
print "found nothing"
end
It works just fine. Any idea why this is?
downcase! returns nil when there is nothing to downcase. If you reassign that to userinput, then userinput can become nil as in your first example. If you use downcase instead, then the error will go away. In your second example, you are not reassigning the result of downcase! to userinput, so userinput is not overwritten as nil.
Related
I am in the process of teaching myself Ruby, and I came onto something I don't quite understand. I am gettign an error of branchingcalc.rb:53:in `<main>': undefined local variable or method `userChoice' for main:Object (NameError)
In my code (below) I have userChoice defined in the method above it. Is the issue I'm having that it's defined in a method, above, or can the if/elsif tree not read the variable because it's defined in a method?
I have removed the userInput method, placing it in the #Begining portion, and that solves my issue, however, I would like the calc to be repeatable.
def userInput
puts "Enter the first number"
num1 = gets.chomp
puts "Enter the second number"
num2 = gets.chomp
puts "What would you like to do?"
puts "1 - Muiltiply"
puts "2 - Divide"
puts "3 - Add"
puts "4 - Subtract"
puts "5 - Exit"
25.times { print "-" }
puts
userChoice = gets.chomp # <- variable defined here
puts
end
# Begining
puts "Branching Clac"
25.times { print "-" }
puts
puts userInput
# Choice tree
if userChoice == "1" # <- undefined variable error here
# ...
elsif userChoice == "2"
# ...
end
You've introduced the userChoice variable in the userInput method. This variable only exists within that method. If you want to communicate this information outside of the method, the best option is to return it from the method, and then use that return value later.
So I have the following code:
print "input please: "
user_input = gets.chomp.downcase!
if user_input.include? "s"
user_input.gsub!(/s/, "th")
else
puts "There is no S in your input"
end
which throws me an error regarding the include method
when I run this it works:
print "input please "
user_input = gets.chomp
user_input.downcase!
if user_input.include? "s"
user_input.gsub!(/s/, "th")
else
puts "There is no S in your input"
end
is it not possible to call multiple methods on a variable?
It is permissible (and recommended!) to chain methods in Ruby as you have done with gets.chomp.downcase!. However, using downcase! as opposed to the form downcase is causing an unexpected behavior in your code. According to the docs, the downcase! form
Downcases the contents of str, returning nil if no changes were made.
So if your input does not contain any upper case letters, downcase! returns nil and that causes an error down the line when you call .include? on it. Try it out with input like this string:
input please: No letter in here!
# prints
There is no S in your input
But the same called without the upper N errors:
input please: no letter in here!
Traceback (most recent call last):
test.rb:4:in `<main>': undefined method `include?' for nil:NilClass (NoMethodError)
If you supply input that does contain upper case characters, you'll get no error with your original code. The fix for this is to use the non-! form:
# Don't use the ! form of downcase
user_input = gets.chomp.downcase
Because the downcase! form is intended to modify a variable rather than modify a transient string such as the string returned by .chomp.
I suspect you intended to puts user_input there also, following your .gsub! call. Your string replacement s to th does work correctly if you add that in.
So I've been messing around with Ruby for the first time after finishing the codecademy course up to "Object Oriented Programming, Part I" and I decided to start making a calculator. For some reason though, I get this error:
calc.rb:13:in `addition': undefined local variable or method `user_input' for main:Object (NameError)
from calc.rb:21:in `<main>'
I'm confused why it doesn't see my "user_input" array. Is it out of the scope of the method? Did I initialize it wrong?
Here's the code so you can see for yourself, it's obviously nothing sophisticated and it's not finished. I'm just trying to test for addition right now.
#!/usr/bin/env ruby
user_input = Array.new
puts "Would you like to [a]dd, [s]ubtract, [m]ultiply, or [d]ivide? "
type_of_math = gets.chomp
def addition
operator = :+
puts "Please enter the numbers you want to add (enter \"=\" to stop adding numbers): "
until gets.chomp == "="
user_input << gets.chomp.to_i
end
sum = user_input.inject(operator)
return sum
end
case type_of_math
when "a"
addition
when "s"
puts "Test for subtraction"
when "m"
puts "Test for multiplication"
when "d"
puts "Test for division"
else
puts "Wrong"
end
Consider this untested variation on your code. It's more idiomatic:
def addition
user_input = []
puts 'Please enter the numbers you want to add (enter "=" to stop adding numbers): '
loop do
input = gets.chomp
break if input == '='
user_input << input
end
user_input.map(&:to_i).inject(:+)
end
Notice that it puts user_input into the method. It also uses the normal [] direct assignment of an empty array to initialize it. Rather than chomp.to_i each value as it's entered it waits to do that until after the loop exits.
Instead of while loops, consider using loop do. They tend to be more easily seen when scanning code.
Also notice there's no return at the end of the method. Ruby automatically returns the last value seen.
I'm New to ruby,learning basics,I want to enter only Integer Values in age field,Need to Throw Not a number when it is a string when executing the following code
puts "Enter Age "
age=Integer(gets) rescue nil
if age.is_a?(Numeric)
puts "Your age is #{age}"
else
puts "Not a Number"
end
if age>25
puts "You are Permitted"
else
puts "Not allowed"
end
getting error as ': undefined method `>' for nil:NilClass (NoMethodError) What am doing wrong ?
The user input was not in a format to give an integer, so by rescue, age became nil. You tried to apply > on it in if age>25, which is not defined.
You wrote puts "Not a number" which will print a message but then your program will keep running as usual. On that line, try replacing "puts" with "raise" and then read about Ruby exceptions.
You don't need to rescue to nil because you're planning to get and respond to whatever the user inputs and you don't need to raise because you don't want the program to exit after the user inputs a non Integer.
This is probably what you need:
age = ""
loop do
puts "Enter Age "
age = gets.chomp
if age.to_i.to_s == age.to_s
puts "Your age is #{age}"
else
puts "Not a Number"
next
end
if age.to_i > 25
puts "You are Permitted"
break
else
puts "Not allowed"
break
end
end until age.to_i.to_s == age.to_s
next will make it go back and do the next loop, and break will break out of the loop.
You can use age.to_i.to_s == age.to_s to really check if age is an integer.
I wrote a small program as the following
print "Your string = "
input = gets.chomp.downcase!
if input.include? "s"
puts "Go yourself!"
end
But I got the error
undefined method `include?' for nil:NilClass (NoMethodError)
if I delete the exclamation mark (!) after downcase, the program runs properly.
I don't understand the reason.
String#downcase! will give you nil, if the string is already in down-cased. So use String#downcase, it is safe. I am sure, you passed from the command line to the method gets, a string which is already down-cased. Replace the line input = gets.chomp.downcase! with input = gets.chomp.downcase. Now you are safe.
String#downcase
Returns a copy of str with all uppercase letters replaced with their lowercase counterparts. If the receiver string object is already, downcased, then the receiver will be returned.
String#downcase!
Downcases the contents of str, returning nil if no changes were made.
One example to demonstrate this -
>> s = "abc"
>> p s.downcase
"abc"
>> p s.downcase!
nil
Now nil is an instance of the class NilClass, which has no instance method called #include?. So you got no method error. This is obvious.
>> nil.respond_to?(:downcase)
false
>> nil.respond_to?(:downcase!)
false
>> s.respond_to?(:downcase!)
true
>> s.respond_to?(:downcase)
true
Do not use downcase! as it can return nil if no changes have been made to the string.
Therefore, the correct code will be:
print "Your string = "
input = gets.chomp.downcase
if input.include? "s"
puts "Go yourself!"
end