Case statement character classification - ruby

I am trying to classify characters using a case statement, but I am not sure how I would go about this in Ruby.
Here is what I have:
case c
when ('a'..'z'), ('A'..'Z'), '$'
puts "#{c} true"
when ' '
#ignore spaces
else
puts "#{c} false"
end
But this is kind of messy and I'd like to simplify it. Is there anyway to simplify this with a regular expression?
Something like:
case c
when '[a-zA-Z$]'
puts "#{c} true"
when '[\s]'
#ignore whitespace
else
puts "#{c} false"
end
How would something like this be done in Ruby?

Absolutely! But the syntax should be like this:
case c
when /[a-zA-Z$]/
puts "#{c} true"
when /\s/
# ignore
else
puts "#{c} false"
end

Related

How to check if an array includes either X or Y

My assignment is to check whether a given input by the user contains the letters "c" or "s". I managed with one but, I simply don't know the correct way to write that.
I know that the problem is "s" || "c".
print 'What can we do for you?'
user_input = gets.chomp
user_input.downcase!
if user_input.empty?
puts 'Well you will have to write something...!'
elsif user_input.include? 's' || 'c'
puts "We got ourselves some 's's and some 'c's"
user_input.gsub!(/s/, 'th')
user_input.tr!('c', 's')
puts "The Daffy version, #{user_input}!"
else
print "Nope, no 's' or 'c' found"
end
simply
elsif user_input.include?("s") || user_input.include?("c")
or something like
%w(s c).any? { |command| user_input.include? command }
This is the perfect example of where regular expressions are fine:
user_input =~ /[sc]/
or:
(user_input.split('') & %w(s c)).any?
You can use Regexp
user_input[/s|c/]
No regexp:
user_input.count('sc') > 0

"Bug" in if statement parameters Learn Ruby The Hard Way

On line 7 of http://learnrubythehardway.org/book/ex35.html, there is a comment stating there is a bug.
When this program runs and you choose a number which contains, neither a "0" nor a "1" it will say it's not a number. How do I get it to detect all numbers?
Here is the code:
def gold_room
puts "This room is full of gold. How much do you take?"
print "> "
choice = $stdin.gets.chomp
# this line has a bug, so fix it
if choice.include?("0") || choice.include?("1")
how_much = choice.to_i
else
dead("Man, learn to type a number.")
end
if how_much < 50
puts "Nice, you're not greedy, you win!"
exit(0)
else
dead("You greedy bastard!")
end
end
You can use regular expression here. \d means any digit, + means one or more times, =~ is a pattern match operator, so:
if choice =~ /\d+/
how_much = choice.to_i
else
dead("Man, learn to type a number.")
end

Smart conversion of double to single quotes in ruby

Problem
In a source file, I have a large number of strings. Some with interpolation, some with special symbols and some with neither.
I am trying to work out if I can replace the simple strings' double quotes with single quotes whilst leaving double quotes for the interpolated and special symbol strings. I would then run this conversion on one or more source code files.
I imagine there is probably a nice regex for this, but I can't quite formulate it.
Example - Code
Imagine the following code:
def myfunc(var, var2 = "abc")
s = "something"
puts "a simple string"
puts "string with a single ' quote"
puts "string with a newline \n"
puts "my #{var}"
end
Example - Result
I would like to turn it into this:
def myfunc(var, var2 = 'abc')
s = 'something'
puts 'a simple string'
puts "string with a single ' quote"
puts "string with a newline \n"
puts "my #{var}"
end
If anyone has any ideas I'd be very grateful!
Assuming that you can read your string from your file by yourself into an array strings:
strings = [ "\"a simple string\"",
"\"string with a single ' quote\"",
"\"string with a newline \n\""
"\"my \#{var}\"" ]
then we would eval them to see how they behave:
$SAFE = 4
single_quoted_when_possible = strings.map { |double_quoted|
begin
string = eval( double_quoted ) # this string, as Ruby sees it
raise unless string.is_a? String
raise unless '"' + string + '"' == double_quoted
rescue
raise "Array element is not a string!"
end
begin
raise unless eval( "'#{string}'" ) == string
"'#{string}'"
rescue
double_quoted
end
}
And that SAFE level 4 is just woodoo, just an acknowledgement from me that we are doing something dangerous. I do not know to what extent it actually protects against all dangers.
In your particular case, you can create a Regexp heuristic, relying on hope that nobody will write "evil" strings in your code, such as /= *(".+") *$/ or /\w+ *\(* *(".+") *\)* *$/. That heuristic would extract some string suspects, to which you could further apply the method I wrote higher above. But I would still have human look at each replacement, and run tests on the resulting code afterwards.

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