如何在Ruby中重启或重用case语句?

时间:2015-02-04 06:21:08

标签: ruby loops refactoring case-statement

在完成codecademy红宝石部分"电影之夜"后,我想扩展案例陈述以允许再次输入。到最后我的代码是:

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

我添加了"退出"案件独立于希望C.R.U.D.直到明确退出该计划。如何更改代码以便能够无限期地重新启动/重用case语句? (另外,是否有更简单/更短的方式来产生与此case语句相同的结果?)

2 个答案:

答案 0 :(得分:1)

围绕它做一个循环。

loop do
    choice = input

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

答案 1 :(得分:1)

好吧,您可以将整个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

在下面的示例中,您可以看到单个方法负责单个功能,而整个类负责管理其任务的委派。这称为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