如何真正讓 Ruby Constants 常數無法被修改

栏目: Ruby · 发布时间: 8年前

内容简介:如何真正讓 Ruby Constants 常數無法被修改

大概翻了一下 Effective Ruby ,覺得其中第四個 Be Awre That Constants Are Mutable 有點意思,記錄下來。

Ruby 裡面大寫開頭的叫做常數,Ruby 開發者可能知道這個常數是可以被事後修改的,雖然會有警告啦,但是還是被修改到了,那有沒有辦法可以真正無法被修改呢? 原來要用 freeze ,而且還需要點技巧。

讓我們看一下代碼:

X = 1

X = 2
(irb):17: warning: already initialized constant X 只是警告而已

# X 變成 2 了 :(

直接 X.freeze 是沒有用的…

X.freeze
X = 3
(irb):20: warning: already initialized constant X

# X 還是變成 3 了 :(

解法:要用一個 module 包起來,然後 freeze 這個 module

module Y
  X = 1
end

Y.freeze

Y::X = 2

# RuntimeError: can't modify frozen Module 丟出錯誤例外,不能修改!

接下來看看使用容器的情況:

class A
  B = ["a", "b", "c"].freeze
  
  def self.mutate
    B[0] << "x"
  end
    
end

A::B << "d"
# RuntimeError: can't modify frozen Array 丟出錯誤例外,不能修改!

A.mutate
A::B # 被修改成 ["ax", "b", "c"] 了,失敗 :(

Ruby 開發者大概已經知道只 freeze 一個容器,只能防止新增和刪除元素,不能阻止個別的元素被直接修改。所以解法是每個元素都要再 freeze 一次:

class A
  B = ["a", "b", "c"].map!(&:freeze).freeze
  
  def self.mutate
    B[0] << "x"
  end
    
end

A::B << "d"
# RuntimeError: can't modify frozen Array 丟出錯誤例外,不能修改!

A.mutate
# RuntimeError: can't modify frozen String 丟出錯誤例外,不能修改!

這樣就搞定啦。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Apache Modules Book

The Apache Modules Book

Nick Kew / Prentice Hall PTR / 2007-02-05 / USD 54.99

"Do you learn best by example and experimentation? This book is ideal. Have your favorite editor and compiler ready-you'll encounter example code you'll want to try right away. You've picked the right......一起来看看 《The Apache Modules Book》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具