2017-02-10 9 views
2

Rubyで少し読んでいます。言語がいかに単純化されているかのように。私はそれを見て、それを私自身で理解しようとしてきました。私はオブジェクトについての助けとそれにデータを追加する方法を探しています。 AthlteというObjectを作成して、そこから.txtまたは.csvファイルのジャージー番号と名前を読み込みたいと思っています。Rubyオブジェクトに追加する

class Athlete 
    def setNumber (jNum) 
    @mynum = jNum 
    end 

    def getNumber 
    return @mynum 
    end 

    def setName (jName) 
    @myname = jName 
    end 

    def getName 
    return @myname 
    end 
end 

私はクラスをどのように設定するのですか?

は、それから私は、ファイルを読み込む:

myAthlete = Athlete.new 

fileObj = File.new(uInput, "r") 
while (line = fileObj.gets) 
    jData = line.split(" ") 
    myAthlete.setNumber(jData.at(0)) 
    myAthlete.setName(jData.at(1)) 
end 
fileObj.close 

私は少し迷子に開始する場所です。 Array.newでこれを試したので、データが完全に分割されていることが分かります。つまり、私はAthleteクラスの内側に配列を作成しようとしています。誰かが私にこれを助けることができますか?

は、だから私の入力ファイルがある場合:

52 Sabathia 
19 Tanaka 
17 Holliday 
24 Sanchez 

それは分割し、私が呼ぶならば、うーんmyAthleteは、(1)それは田中さんのもの

答えて

5

Rubyの門を抱きしめるのは、構文がどれほどクリーンで、どのように多くのRubyスタイルの慣習がそれによって駆動されるかです。例えば、Rubyはgetsetのメソッドに対してアドバイスしますが、アクセサメソッドやミューテータメソッドにはnamename=のようなものが好きです。

はい、あなたは?または!のようにメソッド名の末尾に=を持つことができます。それぞれは特定のものを意味しています。

メソッドで最後に実行する操作がで暗黙的にの戻り値であるため、returnの必要はありません。

はここを念頭に置いて、あなたのコードの簡単なリファクタリングです:

class Athlete 
    def number 
    @number 
    end 

    def number=(value) 
    @number = value 
    end 

    def name 
    @name 
    end 

    def name=(value) 
    @name = value 
    end 
end 

Rubyはあなたが自動的にattr_accessorと呼ばれるためにこれらを生成するメソッドを持っているので、あなたも、これをさらに減らすことができます。またこれらを移入するinitialize方式とすることで少し簡単にあなたの人生を行うことができます。

class Athlete 
    attr_accessor :number 
    attr_accessor :name 

    def initialize(number, name) 
    @number = number 
    @name = name 
    end 
end 

だから、すべて一緒にこれを置くために:

athletes = [ ] 

File.readlines(input) do |line| 
    number, name = line.chomp.split(/\s+/) 

    athletes << Athlete.new(number, name) 
end 

をRubyのコードの多くは、定義するためにブロックを使用しています起こるはずの操作。この場合、readlinesはファイルから読み取られた各行のブロックを呼び出します。これらの行には、末尾に\n改行が含まれており、chompが削除されます。 <<は、配列に何かを追加する簡単な方法です。

変数名とメソッド名をすべて小文字にしてください。大文字はRubyでは意味がありますので、jDatajdataまたはj_dataである必要があります。

更新:この多くを行うには、デバッガに優しい:

class Athlete 
    def inspect 
    "Athlete [%s] %s" % [ @number, @name ] 
    end 
end 
+0

あなたのコードをすべて理解していますので、情報を出力してアスリートを比較するにはどうしたらいいですか?だから私は2番目のアスリート(私の上の 'ダミー'ファイルでは'19 Tanaka ')を取得したい場合は、私はそれをどのような行ですか?アスリート[1]のような何か?私はそれを試して、私は '#'を取得しました。データが保存されている場所へのポインタと思われる数字がたくさんあります。 –

+0

普通の配列なので、 'athletes [1]'はアスリートをインデックス1の位置(2番目のエントリ)。これはもちろん、ファイルに2行あることに依存します。もしあなたが困惑しているならば、 'p athletes'をコンソールにデバッグ出力を表示するための素早い方法として、あるいはもっとうまく' irb'ツールを使って小さなコードを実行し、出力を検査してみてください。 – tadman

+0

'inspect'を定義するちょっとしたスニペットを追加しました。出力がよりフレンドリーに見えます。これらの数値は問題のオブジェクトの 'object_id'です。これは単にデフォルトの検査形式です。 – tadman

3

ファーストをオフにプリントアウトしたいと言うことができますするために、私は希望明示的なgetter/setterを定義する必要はありません。このような何かが

class Athlete 
    attr_accessor :name, :number 

    def initialize(name, number) 
    self.name = name 
    self.number = number 
    end 
end 

あるいは短いを行います。

Athlete = Struct.new(:name, :number) 

そして、選手を作成するには:

athletes = File.foreach(file_path).map do |line| 
    number, name = line.chomp.split(' ') 
    Athlete.new(name, number) 
end 

あなたは今Athlete秒の完全な配列を持つことになります。

+0

ああ、本当にありがとうございました!私はこれを試してみましょう。 :) –

+0

@JohnBarr 'attr_accessor'行に' number'の ':'がないことに注目してください。今私の投稿を修正しました。 –

関連する問題