如何重新启动或重用 Ruby 中的 case 语句?

How to restart or reuse a case statement in Ruby?

在完成 codecademy ruby 部分 "A Night at the Movies" 之后,我想扩展 case 语句以允许再次输入。最后我的代码是:

movies = {
  living_torah: 5,
  ushpizin: 5
}

def input #method for gets.chomp
    gets.chomp.downcase
end

puts "To exit please type 'Quit' or 'Exit'"
puts 'Please type "add", "display", "update" or "delete".'
choice = input

case choice
    when "add"
        puts "Movie Title please:"
        title = input.to_sym
        puts "How would you rate it?"
        rating = input.to_i
        if movies[title].nil?
            movies[title] = rating
            puts "Movie: '#{title.to_s.capitalize}' added with a Rating of # {rating}."
        else
            puts "That Movie already exists. Try updating it."
        end
    when "update"
        puts "Movie Title please:"
        title = input.to_sym
        if movies[title].nil?
            puts "That Title doesn't exist. Please 'add' it."
        else
            puts "Your Movie was found. How would you rate it?"
            rating = input.to_i
            movies[title] = rating
            puts "Movie: '#{title.to_s.capitalize}' updated with a Rating of #{rating}."
        end
    when "display"
        movies.each { |movie, rating| puts "#{movie}: #{rating}" }
    when "delete"
        puts "Which Movie would you like to delete?"
        title = input.to_sym
        if movies[title].nil?
            puts "That Title doesn't exist. Please 'add' it."
        else
            movies.delete(title)
            puts "The Movie '#{title.to_s.capitalize}' has been deleted."
        end
    when "exit", "quit"
        exit
    else
        puts "Invalid choice."
end

我独立于练习添加了 "exit" 案例,希望 C.R.U.D。直到明确退出程序。我如何更改代码才能无限期地 restart/reuse 案例陈述? (此外,是否有 simpler/shorter 方法可以产生与此案例陈述相同的结果?)

绕一圈。

loop do
    choice = input

    case choice
        .
        .
        .
        when "exit", "quit"
            break
        else
            puts "Invalid choice"
    end
end

嗯,您可以将整个 case 语句放在一个循环中。类似于:

loop do

  puts "To exit please type 'Quit' or 'Exit'"
  puts 'Please type "add", "display", "update" or "delete".'
  choice = input

  case choice
    # ...
    when 'exit', 'quit'
      break
  end
end

但是,像这样的大型案例语句并不符合习惯 Ruby。您可能会考虑更多动态选项,例如使用 object.send(method_name, args...).

此外,最好将您的代码放在 classmodule 中。这使得它更容易理解并使事情井井有条。这叫做encapsulation.

在下面的示例中,您可以看到单个方法负责单个功能,而 class 作为一个整体负责管理其任务的委派。这叫做the single responsibility principle

class MyCode
  # store the current state for this object in an accessor.
  # `attr_accessor` defines a read-write property.
  attr_accessor :running

  def add_choice
    # your "add" code here
  end

  def update_choice
    # "update" code
  end

  def exit_choice
    # change the state of this class by marking `running` as false
    self.running = false
  end

  # `alias_method` defines a method called `quit_choice` that
  # runs the same code as `exit_choice`.
  alias_method :quit_choice, :exit_choice

  # reads a single input from the user and returns it,
  # in a normalized form. 
  # "Add" -> "add", "Do Something" -> "do_something"
  def read_choice
    STDIN.gets.chomp.downcase.strip.gsub(/\s+/, '_')
  end

  # Process a single command from the user.
  def process_choice
    choice = read_choice

    # the methods that correspond to user input are named
    # following the same pattern. "add" -> "add_choice"
    method_name = [choice, 'choice'].join('_').to_sym

    # check if the method actually exists.
    if self.respond_to? method_name
      # call the method named by `method_name`
      self.send(method_name)

    else
      # the method doesn't exist. 
      # that means the input was unrecognized.
      puts "Invalid choice #{choice}"
    end
  end

  # this method acts as a "run loop" that continues execution
  # until the `running` state changes.
  def choose
    # define the initial state.
    self.running = true
    # process a single input as long as the state hasn't changed.
    process_choice while self.running
  end
end