2016-09-30 19 views
2

内attr_accessorを持って継承します。問題は、毎回attr_accessorを置く必要なしに、Humanクラスから継承したクラスのStudentを持つことです。 は基本的に私が持っていると思い何これです:私は私はこのような設定attr_accessorを持つクラスは、一定の

Student.new.school 

を行う際attr_accessorは人間ではなく学生からロードされているので

class Student < Human 
    ATTRIBUTES = [:name, :school] 
end 

は、残念ながら、私は、何のメソッドのエラーを取得していません。私の目標を達成するためにどのような工事を使うべきですか?

+0

学生クラスにはattr_accessorがありませんので、学校に属性があることはわかりません。あなたが学校を認知させたいなら、あなたはStudentクラスのattr_accessorを持っているか、Humanクラスのattib_accessorを宣言しておくべきです。 – uday

+1

あなたは 'attr_accessor'が何をしているのか知っていますか?私があなたの質問について理解できるものから、あなたはしません。それは基本的な問題のようです。 –

答えて

2

まあ、配列内に属性を保持する必要はありませんが、Studentクラスはすでにその親クラスに定義されているattr_accessorを継承します。例えば

class Human 
    attr_accessor :name, :gender 
end 

class Student < Human 
    attr_accessor :school 
end 

Studentクラス今持っている:名前:性別と:学校のattr_accessorさん:

> Student.new.respond_to?(:name) 
=> true 
> Student.new.respond_to?(:name=) 
=> true 
> Student.new.respond_to?(:school) 
=> true 
> Student.new.respond_to?(:school=) 
=> true 

人間も応答:nameへと:gender

> Human.new.respond_to?(:name) 
=> true 
> Human.new.respond_to?(:gender) 
=> true 

学校にはない

> Human.new.respond_to?(:school) 
=> false 

これは洗練されたもので、わかりやすいルビーです。

3

私は個人的に@ lcguidaの答えに同意しますが、あなたが提案したパターンに従うことを主張すると少し実験がありました。他の答えは、あなたの解決策がうまくいかなかった理由を既に網羅しています。だから私はここには入りません。

最初に気になったのは、親クラスのself.inheritedコールバックでattr_accessorを呼び出すことでしたが、残念ながら子のボディは後で読み込まれません。それでも、意志があるところには方法があります。 Ruby 2.0以降を使用している場合は、次の実装が有効です。

module LazyAttrAccessorizer 
    def self.extended(obj) 
    TracePoint.trace(:end) do |t| 
     if obj == t.self 
     obj.send :attr_accessor, *obj::ATTRIBUTES 
     t.disable 
     end 
    end 
    end 
end 

class Human 
    extend LazyAttrAccessorizer 
    ATTRIBUTES = [:name] 
    def self.inherited(subclass) 
    subclass.extend LazyAttrAccessorizer 
    end 
end 

class Student < Human 
    ATTRIBUTES = [:name, :school] 
    # ATTRIBUTES = [:school] would also work as expected, but I think you'd like to be literal there. 
end 

> Student.new.respond_to?(:name) 
=> true 
> Student.new.respond_to?(:school) 
=> true 
+0

いいね!間違いなく+1! –

関連する問題