【问题标题】:Can I recall the "case" in case?万一我能回忆起“案例”吗?
【发布时间】:2020-07-24 16:00:28
【问题描述】:

我想在用户写 a 或 b 之前回忆这个案例。我不想使用“案例” 特别。

我只想从用户那里得到输入,而不是得到其他东西。如果他写别的东西,他应该一直写到他写出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

事实上,如果你看它,很多动作都会因为用户输入正确的输入而被执行。我想讲的在这个例子中更详细。根据用户的输入,会有调用方法、添加对象等动作。

我在计算机上编写了大部分代码。但我仍然无法解决我的第一个问题。

【问题讨论】:

    标签: ruby ruby-on-rails-3 switch-statement conditional-statements case


    【解决方案1】:

    使用内核#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控制表达式

    上面的循环结构非常简单,但它需要您考虑下一步需要在哪里使用并中断语句以进行流控制。我自己的直觉是简单地调用一个块,直到它是真实的。例如,核心逻辑可以缩短为:

    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}"
    

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

    另见

    【讨论】:

    • 谢谢,@BobRodes。固定。
    【解决方案2】:

    “我只想做某事直到发生其他事情”是指您使用某种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 语句。就像试图用大锤杀死跳蚤一样。进行检查的最简洁方法是检查输入字符是否包含在所需字符的数组中。

    【讨论】:

      猜你喜欢
      • 2011-03-23
      • 1970-01-01
      • 1970-01-01
      • 2015-03-16
      • 2017-12-22
      • 2021-08-26
      • 2018-01-18
      • 2011-01-04
      • 2017-11-22
      相关资源
      最近更新 更多