我可以回忆一下 "case" 以防万一吗?

Can I recall the "case" in case?

我想回忆这个案例,直到用户写下 a 或 b。我不想使用 "case" 特别。

我只想从用户那里得到输入,但不想得到其他东西。如果他写别的东西,他应该需要写到写a或b为止。

str = gets.chomp.to_s
case str
when "a"
    print "nice a"
when "b" 
    puts "nice b"
else 
    puts "please do it again"
end 

class person
 attr_accessor :name , :surname #and other attributes
end

#There will be a method here and it will run when the program is opened.
#The method will create the first object as soon as the program is opened. 
#The new object that the user will enter will actually be the 2nd object.

puts "What do you want to do?
add
list
out"

process = gets.chomp.to_s

case process
when "add"
    #in here user will add new objects of my class
when "list" 
    #in here user will show my objects
when "out"
    puts "Have a nice day"
else 
    puts "please do it again"   
end

事实上,如果你看一下,很多动作都是由于用户输入了正确的输入而产生的。我想说的在这个例子中更详细。根据用户的输入,会有调用方法、添加对象等动作

我在我的电脑上写了大部分代码。但是我还是没能解决我的第一个问题。

"I just want to do something until something else happens" 是当您使用某种 while 循环时。

你可以这样做:

while true
  str = gets.chomp
  break unless str == 'a' || str == 'b'  
  puts "please do it again"
end 

你也可以使用loop do:

loop do
  str = gets.chomp
  break unless ['a', 'b'].include?(str) 
  puts "please do it again"
end 

puts "Nice #{str}."

Ruby 爱好者倾向于 loop do 而不是 while true。他们做几乎相同的事情。

还有一件事。有一种更简单的方法来写出字符串数组:

loop do
  str = gets.chomp
  break unless %w(a b).include?(str) 
  puts "please do it again"
end 

puts "Nice #{str}."

它看起来并没有简单很多,但是如果您有 10 个字符串,当您不必使用所有这些引号时,输入肯定会更快。

直觉告诉您,您根本不需要使用 case 语句。就像试图用大锤杀死跳蚤一样。最简洁的检查方法是检查输入的字符是否包含在所需字符的数组中。

使用内核#loop

有很多方法可以解决这个问题,但让我们从一个简单的 Kernel#loop 包装现有代码开始,因为这可能是您前进的最简单途径。

loop do
  str = gets.chomp.to_s
  case str
  when "a"
    print "nice a"
  when "b"
    puts "nice b"
  else
    puts "please do it again"
    # restart your loop when not "a" or "b"
    next
  end
  # exit the loop if else clause wasn't triggered
  break
end

使用until控制表达式

上面的循环构造非常简单,但它需要您考虑在何处需要 next 和 break 语句以进行流程控制。我自己的直觉是简单地调用一个块,直到它为真。例如,核心逻辑可以缩短为:

str = nil; until str =~ /a|b/i do str = gets.chomp end; p str

这要短很多,但对用户来说不是特别友好。为了利用这种方法同时使解决方案更具交流性和抗错性,我将以这种方式重构原始代码:

# enable single-character input from console
require 'io/console'

# make sure you don't already have a value,
# especially in a REPL like irb
str = nil

until str =~ /a|b/ do
  printf "\nLetter (a, b): "
  str = STDIN.getch.downcase
end

puts "\nYou entered: #{str}"

虽然不会比您的原始代码短很多,但它可以处理更多边缘情况并避免分支。它对我来说似乎也不那么混乱,但这更像是一个风格问题。这种方法及其语义意图对我来说也更具可读性,但您的里程可能会有所不同。

另请参阅