首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby类常数与继承之谜

Ruby类常数与继承之谜
EN

Stack Overflow用户
提问于 2016-07-09 08:08:50
回答 2查看 537关注 0票数 0

为什么以下两个代码段不产生相同的输出?push|=之间的区别是一个棘手的问题。我认为|=作为一项任务可能会产生影响吗?最重要的是,常量实际上不会在以后的变化中发生变化,我想不是吗?

代码来自于对这个问题的回答。你可以看到它,在这里行动

代码语言:javascript
复制
class LibraryItem

  ATTRIBUTES = ['title', 'authors', 'location']

end

class LibraryBook < LibraryItem

  ATTRIBUTES.push('ISBN', 'pages']

end

puts LibraryItem::ATTRIBUTES
puts LibraryBook::ATTRIBUTES

> ["title", "authors", "location", "ISBN", "pages"]
> ["title", "authors", "location", "ISBN", "pages"]

代码语言:javascript
复制
class Foo

  ATTRIBUTES = ['title','authors','location']

end

class Bar < Foo

  ATTRIBUTES |= ['ISBN', 'pages']

end

puts Foo::ATTRIBUTES
puts Bar::ATTRIBUTES

> ["title", "authors", "location"]
> ["title", "authors", "location", "ISBN", "pages"]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-09 12:01:58

红宝石中的常量有点用词不当。重新分配常量会产生警告:

代码语言:javascript
复制
Foo=1
Foo=2
(irb):5: warning: already initialized constant Foo

但是,没有什么可以阻止您改变实际值本身,push就是这样做的。如果要防止这种情况发生,则可以冻结数组,即

代码语言:javascript
复制
class LibraryItem    
  ATTRIBUTES = ['title', 'authors', 'location'].freeze
end

更改数组的尝试现在将引发异常。不过,只有数组是冻结的,所以您可以执行以下操作

代码语言:javascript
复制
LibraryItem::ATTRIBUTES.first.upcase!

(假设您没有打开冻结的字符串文本),则将允许进行更改。除了单独冻结字符串(或者打开该文件的冻结字符串文本,在ruby 2.3和更高版本上)之外,我不知道有什么方法可以绕过这个问题。

票数 3
EN

Stack Overflow用户

发布于 2016-07-09 08:36:39

在第一个示例中,ATTRIBUTES引用同一个数组,您正在修改它。因此,

代码语言:javascript
复制
puts LibraryItem::ATTRIBUTES
puts LibraryBook::ATTRIBUTES

产生同样的结果。

在第二种情况下,您正在执行a |= b,这是a = a | b的缩写。这将为类ATTRIBUTES创建一个名为Bar的新数组。因此,

代码语言:javascript
复制
puts Foo::ATTRIBUTES
puts Bar::ATTRIBUTES

产生不同的结果。

您可以在这个问题中了解更多关于Ruby赋值操作符的内容。Ruby |=赋值算子

编辑

Ruby使用&|操作符实现了一个小集合的set操作。

单管,|执行联合操作,即只添加唯一的元素。

代码语言:javascript
复制
a = [:foo, :bar, :baz]
a |= [:baz, :buz] # => [:foo, :bar, :baz, :buz]
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38279778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档