一个变量/常量,它继承但不与超类共享,并且不共享命名空间

时间:2013-01-27 00:59:56

标签: ruby variables constants

有没有办法用以下三个属性引入一些变量/常量?

  

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))

如果仅通过分配和引用变量/常量无法完成,那么有没有办法实现具有此属性的访问器方法?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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
相关问题