ruby if-else one-liner with "puts" not working - ruby

I'm trying to do
response = gets.chomp
response == "a" ? puts "yes" : puts "no"
The terminal complains:
syntax error, unexpected ':', expecting keyword_end
response == "a" ? puts "yes" : puts "no"
^
What am I doing wrong?

Here is your error:
response == "a" ? puts "yes" : puts "no"
#=> syntax error, unexpected ':', expecting end-of-input
# response == "a" ? puts "yes" : puts "no"
# ^
Ruby is looking for the first puts' arguments. Since they are not enclosed in parentheses, she assumes they are in a comma-separated list following puts. The first one is "yes", but there is no comma following "yes", so an exception is raised.
Let's try:
response == "a" ? (puts "yes") : puts "no"
#=> syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '('
# response == "a" ? (puts "yes") : puts "no"
# ^
(response == "a" ? puts("yes") : puts "no" raises the same exception.)
I don't know why this doesn't work. The exception says that it is expecting a block (do...end or {..}) or a left parentheses (for enclosing arguments) after the second puts. Kernel#puts calls $stdout.puts. As $stdout returns an IO object, IO#puts is then called, but the doc sheds no light on the problem. Perhaps a reader can offer an explanation.
You could write it as follows:
response == "a" ? (puts "yes") : (puts "no")
or
response == "a" ? puts("yes") : puts("no")
or (best, imo)
puts response == "a" ? "yes" : "no"

Related

Ruby case expression unexpected keyword

I am new to Ruby. My past is in Java. I am trying to use a switch case, apparently known as a case expression in Ruby. I want to accept user input, check that input to see if it includes certain characters, and then substitute those characters with other characters. When I try to run this simple program I get many syntax errors but I am not sure why. Could someone please explain to me if I am using this statement wrong and if I can even use case expression in this situation? Thank you.
empty_string = true
while empty_string do
print "Pleathe enter a thtring: "
user_input = gets.chomp
user_input.downcase!
case
when user_input.include? ("s")
user_input.gsub!(/s/, "th")
when user_input.include? ("ch")
user_input.gsub!(/ch/, "th")
when user_input == ""
puts "You typed noting! You get nothing sir!"
when user_input != ""
empty_string = false
else
puts "There are no 's's in your string."
end
end
puts "Zai jian, #{user_input}"
Below are the errors correlating by line and syntax error
rb.rb:9: syntax error, unexpected ( arg, expecting keyword_then or ',' or ';' or '\n'
when user_input.include? ("s")
rb.rb:11: syntax error, unexpected keyword_when, expecting keyword_end
when user_input.include? ("ch")
^
rb.rb:13: syntax error, unexpected keyword_when, expecting keyword_end
when user_input == ""
^
rb.rb:15: syntax error, unexpected keyword_when, expecting keyword_end
when user_input != ""
^
rb.rb:17: syntax error, unexpected keyword_else, expecting keyword_end
rb.rb:21: syntax error, unexpected keyword_end, expecting end-of-input
BELOW IS THE FIXED CODE THANKS TO #Phlip
empty_string = true
while empty_string do
print "Pleathe enter a thtring: "
user_input = gets.chomp
user_input.downcase!
case
when user_input.include?("s")
user_input.gsub!(/s/, "th")
empty_string = false
when user_input.include?("ch")
user_input.gsub!(/ch/, "th")
empty_string = false
when user_input == ""
puts "You typed noting! You get nothing sir!"
empty_string = true
else
puts "There are no 's's in your string."
end
end
puts "Zai jian, #{user_input}"
The issue was the spaces I had after .include?, #Phlip told me Ruby is space sensitive. I removed the white space and it worked. I ran into an issue with the boolean after and fixed that as well. It works as intended now.
My understanding is that you wish to ask the user for a string until the string contains "s" or "ch". When such a string is found you wish to make one or more substitutions in the string and print out a string containing the modified string. Here is a Ruby-like way of doing that.
user_input = nil
loop do
print "Pleathe enter a thtring: "
user_input = "cheater" # gets.chomp.downcase
case user_input
when /s/
user_input.gsub!('s','th')
break
when /ch/
user_input.gsub!('ch','th')
break
when ""
puts "You typed noting! You get nothing sir!"
else
puts "There are no 's's in your string."
end
end
puts "Zai jian, #{user_input}"
If the user enters an empty string, "You typed noting! You get nothing sir!" and then "Pleathe enter a thtring: " are displayed and gets awaits another entry.
If the user enters a non-empty string that contains no "s"'s or "ch"'s, "Pleathe enter a thtring: " is displayed and gets awaits another entry.
If the user enters "Chester\n" "Zai jian, chethter" is diplayed.
If the user enters "Cheater\N" "Zai jian, theater" is displayed.
If you actually wish to replace all "s"'s and "ch"'s, substitute the following for the first two when statements.
when /s|ch/
user_input.gsub!(/s|ch/,'th')
break
If this is done and user enters "Chester" "thethter" is displayed. (The when line could instead be written when /s/, /ch/, but I don't like that as well, in part because /s|ch/ is still needed as gsub!'s first argument.)
Note that case statements use the method Regexp#===. We therefore see that /s/.===(s) #=> true. Ruby allows us to write that /s/ === 'chester' ("syntactic sugar").
user_input = <anything> must precede the loop to make its value visible after the loop.
See Kernel#loop. For other uses of this method the handling of StopIteration exceptions is very useful when working with enumerators (instances of the Enumerator class).
=== looks a lot like ==, but they should be thought of as entirely different methods.

trailing `_' in number if File.exist?(/home/4000_UW_spreadsheets/input_folio.ods) error

I'm getting some errors I don't understand:
spreadsheet:37: trailing `_' in number
if File.exist?(/home/4000_UW_spreadsheets/input_folio.ods)
^
spreadsheet:37: syntax error, unexpected tINTEGER, expecting ')'
if File.exist?(/home/4000_UW_spreadsheets/input_folio.ods)
^
spreadsheet:37: syntax error, unexpected ')', expecting keyword_end
So what do these errors mean? And how do I fix them..?
From this code:
#!/usr/local/bin/ruby
module Kernel
def cd_to
puts "Type 'go' to begin, press 'h' for help"
input = gets.chomp.downcase
case input
when 'go'
`cd '/'`
`cd '/home/4000_UW_spreadsheets'`
ls_grep
when 'h'
usage_help
else
puts "You're suppose to type 'go' stupid.."
end
end
def ls_grep
puts "Folio number:"
input_folio = gets.chomp
case input_folio
when input_folio =~ /^\d{7}/
`ls -la|grep folio '#{input_folio}'`
file_list.each do |input_folio|
if File.exist?(/home/4000_UW_spreadsheets/input_folio.ods)
puts "Folio number #{input_folio} found"
remove #TO-DO make folio number run against file names
end
end
remove #TO-DO make folio number run against file names
else
puts "Invalid file or directory"
ls_grep
end
end
def remove
puts "Are you sure you want to unlock this folio?(Y/N)"
input = gets.chomp.upcase
case input
when 'Y'
`rm ~folio'#{input_folio}'.lock`
when 'N'
puts "Exiting..."
exit
else
puts "Error, exiting..."
exit
end
end
def usage_help
puts <<-EOT.gsub(/^\s*>/, ' ')
>
>This program will unlock spreadhseets quickly and efficiently
>To use follow the prompts and type in the folio number
>Which should match the file name
>
>In the situation where the folio number doesn't match
>The file name, get the file name and use it to unlock
>The spreadsheet
>
EOT
end
end
cd_to
As for the second error: you just need to add quotation marks around the path, like this
File.exist?("/home/4000_UW_spreadsheets/input_folio.ods")

Ruby - Adding more than one includes on an if statement

I have the following code which works fine
if user_input.include? "s"
user_input.gsub!(/s/ "th")
else
print "Nothing to change"
end
But when I want to add another include like so it does not recognize the elsif How do I add these includes together?
if user_input.include? "s"
user_input.gsub!(/s/ "th")
elsif user_input.include? "cee"
user_input.gsub!(/cee/ "th")
else
print "Nothing to change"
end
Since gsub! returns nil if nothing changed, your can write your example just like this:
unless user_input.gsub!(/s|cee/ "th")
print "Nothing to change"
end
This is because of flow of execution of if else statement.
If condition in 'if' matches it will not execute 'elseif' block..
if user_input.include?('s') or user_input.include?('cee')
user_input.gsub!(/s/,"th").gsub!(/cee/,"th")
else
print "Nothing to change"
end
Your code show the error :
SyntaxError: unexpected ')', expecting keyword_end
You forget the commas in gsub
if user_input.include? "s"
user_input.gsub!(/s/, "th")
elsif user_input.include? "cee"
user_input.gsub!(/cee/, "th")
else
print "Nothing to change"
end
Edit :
If you want to make both replacement, you need to change to :
old_value = user_input
if user_input.include? "s"
user_input.gsub!(/s/, "th")
end
if user_input.include? "cee"
user_input.gsub!(/cee/, "th")
end
if user_input == old8value
print "Nothing to change"
end
Once the first if is matched, the rest are skipped.
For your particular use case, I would suggest that you use a single gsub like so:
regexp = /s|cee/
if string.match(regexp)
string.gsub!(regexp, "th")
else
"Nothing to gsub!"
end

How can I logically OR two include? conditions in Ruby?

I am starting learn Ruby, need some help with the include? method.
The below code works just fine:
x = 'ab.c'
if x.include? "."
puts 'hello'
else
puts 'no'
end
But when I code it this way:
x = 'ab.c'
y = 'xyz'
if x.include? "." || y.include? "."
puts 'hello'
else
puts 'no'
end
If gives me error when I run it:
test.rb:3: syntax error, unexpected tSTRING_BEG, expecting keyword_then or ';' o
r '\n'
if x.include? "." || y.include? "."
^
test.rb:5: syntax error, unexpected keyword_else, expecting end-of-input
Is this because the include? method cannot have handle logic operator?
Thanks
The other answer and comment are correct, you just need to include parenthesis around your argument due to Ruby's language parsing rules, e.g.,
if x.include?(".") || y.include?(".")
You could also just structure your conditional like this, which would scale more easily as you add more arrays to search:
if [x, y].any? {|array| array.include? "." }
puts 'hello'
else
puts 'no'
end
See Enumerable#any? for more details.
It's because of Ruby parser, it can't recognize the difference between the passing an arguments and logical operators.
Just modify your code a little bit to distinguish the arguments and operator for Ruby parser.
if x.include?(".") || y.include?(".")
puts 'hello'
else
puts 'no'
end

Ruby include? in an if-statement

Why does this result in a syntax error "syntax error, unexpected keyword_end, expecting $end"?:
if "test".include?"te" || "test".include?"fail"
puts "true"
end
The following works:
fail = "test".include?"fail"
if "test".include?"te" || fail
puts "true"
end
Another solution: replace operator "||" with "or" which has lower precedence so you can leave parentheses omitted:
if "test".include?"te" or "test".include?"fail"
puts "true"
end
Use parentheses with those include? arguments.
if "test".include?("te") || "test".include?("fail")
puts "true"
end
You must use a brace around the 2nd parameter.
if "test".include?("te") || "test".include?("fail")
puts "true"
end
or
if "test".include? "te" || ("test".include? "fail" )
puts "true"
end
if "test".include?("te") || "test".include?("fail")
puts "true"
end

Resources