在内部重新启动Ruby程序

在内部重新启动Ruby程序,ruby,application-restart,Ruby,Application Restart,我正在用Ruby编写一个非常简单的地下城冒险游戏(新手练习)。我希望在整个过程中按名称对播放器进行寻址,因此我自然希望确保如果一个播放器向我的播放器初始化方法传递一个空名称,如果告诉他们不能这样做,然后提示他们重试 class Player attr_accessor :name, :location def initialize(name) if name.empty? == false @name = name els

我正在用Ruby编写一个非常简单的地下城冒险游戏(新手练习)。我希望在整个过程中按名称对播放器进行寻址,因此我自然希望确保如果一个播放器向我的播放器初始化方法传递一个空名称,如果告诉他们不能这样做,然后提示他们重试

class Player
    attr_accessor :name, :location

    def initialize(name)
        if name.empty? == false
            @name = name
        else
            puts "You did not enter your name! Try again, please"
            load 'game.rb'
        end
    end
end
文件名是'game.rb',所以每次玩家决定不输入他们的名字时,我基本上都会在这里重新加载整个文件。这是愚蠢的

这是可行的,但最糟糕的是……我必须“聪明地”知道我退出程序的地方,这样玩家就不会受到这样的事实的影响:我基本上是对每个人都进行《盗梦空间》,每次玩家开始一个新游戏时,在游戏中启动一个游戏,而忽略了输入他们的名字。例如,如果他们三次没有注意到他们需要输入自己的名字,因为他们没有注意到,我实际上有四个游戏正在运行(最初的,三个是由于没有输入他们的名字而提示的),他们或者需要在玩累了的时候结束每一个游戏,要不然,我就得在一个关键词上硬着头皮退出整个过程

我的问题是:有没有办法写下我的错误“你没有进入…”退出当前游戏会话,然后重新启动游戏?我真正想做的就是确保一个空字符串不会传递给我的initialize方法,可能是通过引发一个异常,然后在脚本开始时重新开始,而不必进行游戏中的游戏


这里有一个完整代码的链接,以获取更多信息:

如果不查看整个游戏结构,很难知道,但是您的主文件可能看起来像

game_initialized = false
while ! game_initialized
  begin
    # here, initialize the game, including initialization
    game_initialized = true
  rescue NoNameError
    # do nothing, but it will restart the game
  end
end
# now play the game
在构造函数中,添加

class NoNameError < Exception
end

class Player
  attr_accessor :name, :location

  def initialize(name)
    if name.empty? == false
      @name = name
    else
      puts "You did not enter your name! Try again, please"
      raise NoNameError
    end
  end
end
类非错误

这应该能让你走了。

我认为文森特的答案是好的,当然比我的答案更糟糕,但一个简单的方法是在游戏开始时做类似的事情:

print "Welcome!  "
in_name = ""
while true
  puts "What is your name?"
  in_name = gets.chomp
  in_name.empty? ? (puts "You must enter a name before continuing") : break
end
例如:

Welcome!  What is your name?

You must enter a name before continuing
What is your name?
Anthony

如果您想让自己的逻辑在播放器中,可以尝试以下方法:

class Player
  attr_accessor :name, :location

  def initialize(name)
    @name = keep_asking_for_name_if_not_already_entered(name)
  end

  def keep_asking_for_name_if_not_already_entered(name)
    return name unless name.empty?
    loop do
      puts 'You did not enter your name! Enter a name, please:'
      name = gets.chomp
      break(name) unless name.empty?
    end
  end
end

尝试重新加载game.rb听上去完全是错误的做法-为什么不反复调用get(或您用来读取输入的任何东西),直到提供有效的输入。@FrederickCheung啊,这样做更有意义。嗯。您是否建议围绕gets调用进行一个简单的循环来处理这个问题?虽然这会起作用,但我不认为缺少名称是一种例外情况。我想在你得到一个有效的名字之前,一直问下去也是很容易的。谢谢!我真的很喜欢你在这里做的事。这就是我一直想做的,但我不能完全控制住自己。很明显,我的所有代码(假设我是一个恶心的人,把所有代码都放在一个文件中)基本上都在“开始”和“拯救”之间,对吗?然后我可以添加我可能需要的任意数量的救援,包括我的非米错救援…@SkeletorDan据我所知,你不需要将整个游戏都放在begin/rescue块中,只需要初始化。我将更新anwser以反映这一点。@JustinWood是什么让你认为这是一个例外情况?在这种情况下,使用异常只是控制流的一种非常方便的方法。这就是异常的用途。@VincentFourmond异常不应用作控制流。此场景中可以使用各种控制流构造。例外旨在处理特殊情况。这是一个关于何时应该使用异常的合理解释。谢谢@Anthony!我同意,Vincent有很好的洞察力,我会在我有时间的时候实施,但我使用了你的实施,并结合了Frederick在顶部的评论,使其按照我预期的方式工作。关于长时间查看自己的代码……不管怎样,“break”是否本质上会使while循环为false,从而有效地结束它?它实际上不会将其设置为false,但会终止while块。更多的细节是有道理的。我可能不应该在initialize方法中运行逻辑,而是创建一个方法来处理它。说得好!比我的尝试干净多了。