1

「contents.txt」という名前のファイルがあり、その中に YAML 形式のテキストが含まれています。

コマンドラインで次のように渡しますruby Minesweeper.rb contents.txt

次に、ロード機能があります。

def self.load
  grid = YAML::load(File.open(ARGV[0]))
  grid
end

メインplayループ内で、コマンドを使用してユーザーから入力を受け取りますinput = gets.chomp

問題は、入力がユーザーから何も取得されていないため、ユーザーから入力を取得する前にエラーが発生することです。代わりに、ファイルからの入力などのランダムな入力を実行するようにコードが構成されていないため、もちろんエラーが発生するまで、ファイルのすべての行を取得してループを実行しています。

YAML::loadこれは私が気付いていない副作用ですか?どうすればこれを乗り越えることができますか?

4

2 に答える 2

2

単純な古い関数のように見える Ruby のほとんどのものは、実際には からのメソッドです。特に、実際に を呼び出しているKernelと言う場合です。細かいマニュアルから:s = getsKernel#getsKernel

gets(sep=$/) → 文字列または nil
gets(limit) → 文字列または nil
gets(sep,limit) → 文字列または nil

(または)$_のファイルのリストから、またはコマンド ラインにファイルが存在しない場合は標準入力から次の行を返します (および に割り当てます)。ARGV$*

そのため、(インスタンスgets内にいなくても) は、設計上、コマンド ラインで指定されたファイルから読み取ります。IOこれは、コマンド ライン フィルターや 1 回限りruby -eのスクリプトを簡単に記述できるようにするために行われます。たとえば、標準入力を検索するためgrep pancakesだけにファイルを検索すると言うことができます。grep

標準入力から読み取りたい場合は、次のように言う必要があります。

input = $stdin.gets.chomp
于 2013-07-23T04:06:08.200 に答える
1

@mu-is-too-short の回答に加えて、おそらくコードを少し調整する必要があります。

self.load本当にクラスメソッドになりたいですか? ARGV[0]その文脈では利用できないと思います。

インスタンスを提供するだけのFile.openではなく、 File.read (別名、IO.read)が必要だと思います。その後、 を呼び出す必要があります。Filefile.read

require 'yaml'

class Runner
  attr_reader :file_name

  def initialize(file_name)
    @file_name = file_name
  end

  def load
    file = File.read(file_name)
    ::YAML::load(file)
  end
end

Runner.new(ARGV[0]).load
于 2013-07-23T04:13:22.097 に答える