我在在线测试中遇到了这个问题。我有这个课:
class DocumentStore
def initialize(capacity)
@capacity = capacity;
@documents = []
end
def get_documents
return @documents
end
def add_document(document)
raise 'Document store is full' if @documents.length >= @capacity
@documents.push(document)
end
def inspect
return "Document store: #{@documents.length}/#{@capacity}"
end
end
我想通过get_documents
返回存储数据,并防止用户通过返回的对象(例如,
ds = DocumentStore.new(3)
ds.add_document("Doc1")
docs = ds.get_documents
docs.push("Doc2")
puts ds.inspect # this should just print ["Doc1"]
答案 0 :(得分:4)
只需将Object#freeze
与Object#dup
一起调用即可完成。 freeze 不返回冻结的副本,而是冻结self
并返回self
。这意味着没有 dup 调用,您也无法在类内部修改数组。
def get_documents
return @documents.dup.freeze
end
您还可以选择仅使用 dup ,返回浅表副本。允许调用者修改数组而不影响@documents
。
def get_documents
return @documents.dup
end
注意:请记住,没有其他方法可以检索数组。 Ruby总是返回方法所做出的最后一条语句。这意味着您的方法DocumentStore#add_document
将返回@documents.push(document)
的结果。
Append —将给定对象推到该数组的末尾。此表达式返回数组本身,因此可以将多个追加链接在一起。另请参见#pop,以了解相反的效果。