1

次の3つのプロパティで変数/定数を導入する方法はありますか?

a)独自のクラスに割り当てられていない場合、スーパークラスの値を継承します。

b)スーパークラス以外の他のクラスの値を継承しません(名前空間を共有している場合でも)。

c)独自のクラスに割り当てられた場合、スーパークラスの値は上書きされません。

クラスインスタンス変数を使用すると、a)が満たされません。

class A; @foo = :foo end
class B < A; @foo end # => nil  (Does not satisfy (a))
class A; class C; @foo end end # => nil (Satisfies (b))

class B < A; @foo = :bar end
class A; @foo end # => :foo  (Satisfies (c))

クラス変数を使用すると、c)が満たされません。

class A; @@foo = :foo end
class B < A; @@foo end # => :foo  (Satisfies (a))
class A; class C; @foo end end # => NameError (Satisfies (b))

class B < A; @@foo = :bar end
class A; @foo end # => :bar  (Does not satisfy (c))

定数を使用すると、b)が満たされません。

class A; Foo = :foo end
class B < A; Foo end # => :foo  (Satisfies (a))
class A; class C; Foo end end # => :foo (Does not satisfy (b))

class B < A; Foo = :bar end
class A; Foo end # => :foo  (Satisfies (c))

私はこのように振る舞う何かが欲しいです:

class A; something = :foo end
class B < A; something end # => :foo  (Satisfies (a))
class A; class C; something end end # => nil or Error (Satisfies (b))

class B < A; something = :bar end
class A; something end # => :foo  (Satisfies (c))

変数/定数を割り当てて参照するだけでは実行できない場合、このプロパティを持つアクセサメソッドを実装する方法はありますか?

4

2 に答える 2

3

必要な特定のプロパティを使用して、独自の種類のアクセサを作成する必要があります。例えば、

module InheritableProperty
  def property
    @property || superclass.property
  end
  def property=(value)
    @property = value
  end
end

class A
  extend InheritableProperty
end
class B < A
  extend InheritableProperty
  class C
    extend InheritableProperty
  end
end

A.property = 1
A.property # => 1
B.property # => 1
B::C.property # error

A.property = 1
B.property = 2
A.property # => 1
B.property # => 2
B::C.property # error

A.property = 1
B.property = 2
B::C.property = 3
A.property # => 1
B.property # => 2
B::C.property # => 3
于 2013-01-27T02:44:57.157 に答える
0

joshuanapoliによって提案された線に沿って、私はこれで行くことにしました:

class A
  def self.foo; defined?(@foo) ? @foo : superclass.foo end
end

class A; @foo = :foo end
class B < A; foo end # => :foo
class A; class C; foo end end # => Error
class B < A; @foo = :bar end
class A; foo end # => :foo
于 2013-01-27T03:53:13.890 に答える