0

我一直在筛选之前关于 stackoverflow 的问题和答案,并且我已经弄清楚了我的大部分问题。我发现如果不将函数调用放在 proc 或类似容器中,我就无法在哈希中放置函数调用。

我最终要做的是显示一个菜单,获取用户输入,然后遍历哈希,并运行指定的函数:

def Main()
    menu_titles = {"Answer1" => Proc.new{Choice1()}}
    Menu(menu_titles)
end

def Choice1()
    puts "Response answer"
end

def Menu(menu_titles)
   menu_titles.each_with_index do |(key, value),index|
        puts "#{index+1}. #{key}"
   end 

user_input = 0 

   menu_titles.each_with_index do |(key, value), index|
        if index.eql?(user_input)
           menu_titles[value]
           break
        end 
   end 
end

Main()

我现在遇到的问题是我没有输入我的哈希要求的函数。无论我使用 return 还是“puts”,我要么得到一个空行,要么什么都没有。如果有人对我的代码有其他建议,我也会全神贯注。老实说,我不喜欢使用 procs,但这主要是因为我不完全知道它们是如何工作的以及在哪里使用它们。

现在我的菜单有:

user_input = 1
if user_input == 1
   Choice1()
...
end
4

1 回答 1

2

这是我将如何重构它:

class Menu
  attr_reader :titles

  # initialize sets up a hard-coded titles instance variable,
  # but it could easily take an argument.
  def initialize 
    @titles = { 
      "Answer1" => Proc.new{ puts "choice 1" },
      "Answer2" => Proc.new{ puts "choice 2" } 
    }
  end

  # This is the only public instance method in your class,
  # which should give some idea about what the class is for
  # to whoever reads your code
  def choose
    proc_for_index(display_for_choice)
  end

  private

    # returns the index of the proc.
    def display_for_choice
      titles.each_with_index { |(key,value), index| puts "#{index + 1}. #{key}" }
      gets.chomp.to_i - 1 # gets will return the string value of user input (try it in IRB)
    end 

    # first finds the key for the selected index, then 
    # performs the hash lookup.
    def proc_for_index(index)
      titles[titles.keys[index]]
    end
end

如果您对 Ruby(或一般的面向对象编程)很认真,我强烈建议您了解将代码打包成特定于行为的类的优势。此示例允许您执行此操作:

menu = Menu.new
proc = menu.choose
#=> 1. Answer1
#=> 2. Answer2
2 #(user input)

proc.call
#=> choice 2

你实际上可以在一行上运行它:

Menu.new.choose.call
于 2012-11-13T20:59:45.497 回答