我是 Ruby 新手,所以请原谅可能的菜鸟问题,但到目前为止,谷歌在这方面一直没有帮助。
我在父类中定义了一个类常量
Items = [[1, 3, 5], [2, 4, 6]]
然后我有一个子类,我想在其中将数组 [1, 5, 9] 添加到 Items 数组中。你能以这种方式引用超级/重新定义常量吗?
就像是
Items = super.Items.concat([1, 5, 9])
我希望不需要将 Items 定义与附加项目一起复制到我的子类中。
我是 Ruby 新手,所以请原谅可能的菜鸟问题,但到目前为止,谷歌在这方面一直没有帮助。
我在父类中定义了一个类常量
Items = [[1, 3, 5], [2, 4, 6]]
然后我有一个子类,我想在其中将数组 [1, 5, 9] 添加到 Items 数组中。你能以这种方式引用超级/重新定义常量吗?
就像是
Items = super.Items.concat([1, 5, 9])
我希望不需要将 Items 定义与附加项目一起复制到我的子类中。
常量在它们定义的类或模块中以名称分隔。它们通过通常的祖先路径解决。在您的子类中,您可以定义一个与超类中同名的常量,并且初始化它的表达式可以引用超类的常量,因为子类的常量要等到初始赋值之后才会定义。像这样:
$ pry
[1] pry(main)> class A; Items = [[1, 3, 5], [2, 4, 6]]; end
=> [[1, 3, 5], [2, 4, 6]]
[2] pry(main)> class B < A; end
=> nil
[3] pry(main)> class B; Items; end
=> [[1, 3, 5], [2, 4, 6]]
[4] pry(main)> A::Items
=> [[1, 3, 5], [2, 4, 6]]
[5] pry(main)> B::Items
=> [[1, 3, 5], [2, 4, 6]]
[6] pry(main)> class B; Items = Items.dup << [7,8,9]; end
=> [[1, 3, 5], [2, 4, 6], [7, 8, 9]]
[7] pry(main)> A::Items
=> [[1, 3, 5], [2, 4, 6]]
[8] pry(main)> B::Items
=> [[1, 3, 5], [2, 4, 6], [7, 8, 9]]
派生新常量时,dup
如果您打算使用变异方法(如Array#<<
)对其进行修改,请注意原始常量。看陷阱:
[9] pry(main)> class A; Foo = [[1,2],[3,4]]; end
=> [[1, 2], [3, 4]]
[10] pry(main)> A::Foo
=> [[1, 2], [3, 4]]
[11] pry(main)> class B; Foo = Foo << [5,6]; end
=> [[1, 2], [3, 4], [5, 6]]
[12] pry(main)> B::Foo
=> [[1, 2], [3, 4], [5, 6]]
[13] pry(main)> A::Foo
=> [[1, 2], [3, 4], [5, 6]]
[14] pry(main)> B::Foo.object_id == A::Foo.object_id
=> true
[15] pry(main)> B::Items.object_id == A::Items.object_id
=> false
您可以显式引用父命名空间中的常量,而无需使用命名超类Class#superclass
[16] pry(main)> class B; superclass::Items; end
=> [[1, 3, 5], [2, 4, 6]]
常量查找在 Ruby 中并不总是非常明显,特别是因为它通常没有作用域(例如,我们写String
, not ::String
)
您可以在子类中覆盖它。您可以通过访问superclass
:
class C < Base
CONST = build_on(superclass::CONST)
end
但是,您必须小心如何从实例和单例方法访问常量:
class Base
FOO = [42]
def self.naive
FOO
end
def naive_ins
FOO
end
def self.aware
self::FOO
end
def aware_ins
self.class::FOO
end
end
class C < Base
FOO = superclass::FOO + [:bar]
end
C.naive # => [42]
C.new.naive_ins # => [42]
C.aware # => [42, :bar]
C.new.aware_ins # => [42, :bar]
常量的作用域是它们定义的类。因此,您可以根据需要重新定义子类中的常量。