如何防止方法改变其参数?

时间:2012-04-03 20:39:06

标签: ruby string concatenation mutable

我想使用的方法是gem并在此处获取(第17-42行):https://github.com/rails/rails/blob/master/railties/lib/rails/generators/actions.rb

正如您所看到的,name被分配到第19行的第一个arg,然后在第23行将message分配给name,最后message被突变第26行<<。不幸的是,这意味着我作为第一个参数传入的字符串在方法之外发生变异。

我有一个数组哈希,并按如下方式迭代它们:

groups = { foo: %w(foo, bar), bar: %w(foobar) }

groups.each do |group, gems|
  gems.each do |name|
    gem(name, "42")
  end
end

之后由于gem

内部的突变,我的哈希看起来像这样
groups => { foo: ["foo (42)", "bar (42)"], bar: ["foobar (42)"] }

如何防止这些字符串(以及散列及其数组)发生变异但不破坏方法?

2 个答案:

答案 0 :(得分:5)

你无法阻止该方法改变其参数(除了提交错误报告,因为它不应该这样做。)

你可以做的是用你的字符串克隆来调用方法,如下所示:

gem(name.dup, "42")

答案 1 :(得分:1)

您可以使用name.dup

来调用它
gem(name.dup, "42")

背景:使用gem(name)将参数传递给方法。在被调用方法内的任何修改,也将改变原始变量。

使用name.dup制作对象的副本。此副本在被调用方法中被修改,但原始值未更改。


警告:dup始终不起作用,取决于数据。 dup未制作深层副本。见这个例子:

arr = ['a', 'b']
arr.dup.map{|x| x << '1'}
p arr #["a1", "b1"]

说明:复制数组arr,但不复制数组内的内容。 在map内,您可以修改复制数组的数据。但原始数据和复制数组的元素是相同的。所以你也改变了原始数组的内容。