2013-05-20 5 views
18

私はのようなコードを参照してください。一つのクラスでattr_accessorとinitializeメソッドを混在

class Person 
    def initialize(name) 
    @name = name 
    end 
end 

私はこれは私がperson = Person.newのような事をすると、他の方法と同様に他の場所で私のクラスで@nameを使用することができます理解しています。次に、私はこのようなコードを見た:

class Person 
    attr_accessor :name 
end 

... 

person = Person.new 
person.name = "David" 

私はこれらの2つのメソッドメッシュで失われています。 def initialize(name)の具体的な用途は何ですか?私はattr_accessorが私に読み書きを許可すると思います。つまり、彼らは2つの別々の方法です。はい? def initializeattr_accessorについての説明とそのメッシュの仕組み

答えて

21

initializeattr_accessorはお互いに何の関係もありません。

def initialize(name) 
    @name = name 
    # or 
    # self.name = name 
end 

しかし、あなたはそれを行う必要はありません:あなたはオブジェクトの作成時に名前を設定したい場合は、初期化子でそれを行うことができます

def name 
    @name 
end 

def name=(val) 
    @name = val 
end 

attr_accessor :nameは、メソッドのカップルを作成します。作成後に名前を設定することができます。

p = Person.new 
p.name = "David" 
puts p.name # >> "David" 
+1

初期化メソッドは、オブジェクトの作成時に値を初期化する方法として使用されます。これは必須ではありませんが、オブジェクトに多数の属性がある場合は、時間を費やすのではなく、作成後にすべての属性を設定するのではなく、すぐにすべてを行うことができます。はい? – David

+0

@David並べ替え注意すべき点は、オブジェクトに多くの属性がある場合、イニシャライザは急速に順序付けられたパラメータの無駄になるということです。そのため、(a)パラメータの名前を付けました。また、(b)地図を使用して建設現場での可読性を高めることができます。 –

+0

@DaveNewtonあなたは両方の非常に短い例がありますか?私はあなたが何を意味しているかを知っていると確信したいと思います。私たちは今、名前付きパラメーターを持っていると言いますが、私たちはそうしなかったことを示唆していますか?方法を定義する際に、私は「これとそのパラメータを取り入れたい」と言い切ったことがありますか? – David

14

ここでは、お探しの答えはClasses and methodsです。注意深くお読みください。ここで

は、リンクから良いドキュメントです:

クラスとメソッド

は、今、私たちは私たちの非常に自身のAddressクラスを作成する準備ができました。簡単に始めましょう。 「ストリート」フィールドだけを含む住所から始めましょう。

これは、クラスを定義する方法である:

class Address 
    def initialize(street) 
     @street = street 
    end 
end 

だが、この見ていきましょう:

  • classキーワードは、クラスを定義します。

  • このクラスの内部でメソッドを定義することによって、このクラスに関連付けます。

  • initializeメソッドは、実際にデータ構造を構築するメソッドです。すべてのクラスにinitializeメソッドが含まれている必要があります。

@streetはオブジェクト変数です。ハッシュのキーと同様です。 @記号は@streetをオブジェクト変数として区別します。 Addressクラスのオブジェクトを作成するたびに、このオブジェクトには@street変数が含まれます。

このクラスを使用してアドレスオブジェクトを作成しましょう。

address = Addres.new("23 St George St.") 

これだけです。アドレスがクラスのオブジェクトになりました。アドレス オブジェクト内のデータを読み取る

アドレスオブジェクトのデータを読み込みたいとします。

class Address 
    def initialize(street) 
     @street = street 
    end 

    # Just return @street 
    def street 
     @street 
    end 
end 

今の方法のアドレス#ストリートは、あなたが住所の通りを読むことができます。これを行うために、我々はこのデータを返すメソッドを記述する必要があります。外で見ることができるオブジェクトのプロパティは、属性と呼ばれます。この場合、通りは属性です。特に、読み取り可能な属性です。

は、我々はまた、データを変更するメソッドを定義することができます

class Address 
    attr_reader :street 
    def initialize(street) 
     @street = street 
    end 
end 

オブジェクト内のデータを変更する:属性のこの種は非常に一般的ですので、Rubyはattr_readerキーワードを通じて、あなたにショートカットを提供していますオブジェクト内に

class Address 
    attr_reader :street 
    def initialize(street) 
     @street = street 
    end 
    def street=(street) 
     @street = street 
    end 
end 

Rubyはストリート=メソッドの使用にはかなりスマートです:あなたは、通りや=ベッテンスペースを置くことができます

`address.street = "45 Main St`." 

注意してください。アドレスデータを変更できるようになったので、initializeメソッドを単純化して、空白文字列 ""にストリートをデフォルト設定するだけです。

class Address 
    attr_reader :street 
    def initialize 
     @street = "" 
    end 
    def street=(street) 
     @street = street 
    end 
end 

address = Address.new 
address.street = "23 St George St." 

これは、簡素化の多くのように思えないかもしれませんが、我々は都市、州および郵便番号フィールド、および複数のメソッドを追加するときに、このクラス定義は少し簡単になります。

現在、通りは書き込み可能な属性です。前と同じように、あなたはattr_writerとそのように宣言することができます。

class Address 
    attr_reader :street 
    attr_writer :street 
    def initialize 
     @street = "" 
    end 
end 

は非常に多くのデータ

へのアクセスには、読み書きの両方の属性である属性を持っています。 Rubyでは、attr_accessorを使用してこれらをまとめて処理できます。私はこれらを「アクセシビリティアトリビュート」と呼んでいると思いますが、私はそれらが呼び出されるのを見たことはありません。

この知識によって、アドレスブック構造全体を簡単に定義することができます。判明しているように、attr_accessorとfriendsはすべて複数の引数を受け入れます。

class Address 
    attr_accessor :street, :city, :state, :zip 
    def initialize 
     @street = @city = @state = @zip = "" 
    end 
end 
+3

実際の内容をリンクに記載するのではなく、答えに含めるようにしてください。リンクのみの回答は、(a)回答が自分の上に立っていない、(b)リンクがダウンすると役に立たないよりも悪いという理由で、ぶつかってしまう。 –

+3

さようなら!与えて:) –

+0

@DaveNewton私はやった。もう私は追加する必要がありますか?コメントしてください。 –

4

私はあなたがコンストラクタとしてinitializeを考えると思います。正確に言えば、そうではありません。デフォルトのコンストラクタは、クラスのnewメソッドであり、そのメソッドによってinitializeが呼び出されます。 initializeを定義しない場合は、initializeがコンストラクタ自体ではないため、newでオブジェクトを作成することはできます。その場合、デフォルトのinitializeは何もしません。 initializeを定義すると、オブジェクト作成直後に呼び出されます。

@foo = ...attr_accessor :fooというステートメントは異なります。前者はインスタンス変数@fooに値を割り当てますが、後者ではfoofoo=の方法で@fooにアクセスできます。後者がなければ、そのまま直接記述することで@fooにアクセスできます。

-1

C++とは異なり、RubyでJavaインスタンス変数は、デフォルトでプライベートている(彼らはa.instance_variable_getを使用してアクセスすることができますように部分的に:@x)

例:

class Dda 
    def initialize task 
     @task = task 
     @done = false 
    end 
    end 
item = Dda.new "Jogging" # This would call the initializer and task = Jogging would 
be set for item 
item.task # would give error as their is no function named task to access the instance 
variable. 

我々はしているが、値をitemに設定しますが、インスタンス変数がルビのプライベートなので、何もすることはできません。ゲッターのための コード:item.taskが、それは価値 だとセッターを使用して私たちにいつでもインスタンス変数に値を提供するための柔軟性を提供します返すことを確実にするゲッターを使用して

def task 
    @task 
end 
#for getter 
def task=task 
    @task = task 
end 

関連する問題