为什么这个Ruby方法会通过它';s的引证论证

为什么这个Ruby方法会通过它';s的引证论证,ruby,parameters,reference,pass-by-reference,pass-by-value,Ruby,Parameters,Reference,Pass By Reference,Pass By Value,我回答了这个问题,偶然发现了一些奇怪的东西。 Ruby按值传递参数,但变量本身是引用。 那么,为什么第一个方法似乎通过引用传递其参数呢 require 'set' require 'benchmark' def add_item1!(item, list) list << item unless list.include?(item) end def add_item2(item, list) list |= [item] end def add_item3(item,

我回答了这个问题,偶然发现了一些奇怪的东西。 Ruby按值传递参数,但变量本身是引用。 那么,为什么第一个方法似乎通过引用传递其参数呢

require 'set'
require 'benchmark'

def add_item1!(item, list)
  list << item unless list.include?(item)
end

def add_item2(item, list)
  list |= [item]
end

def add_item3(item, list)
  set = Set.new(list)
  set << item
  list = set.to_a
end

array1 = [3,2,1,4]
add_item1!(5, array1)
p array1 # [3, 2, 1, 4, 5]

array2 = [3,2,1,4]
add_item2(5, array2) 
p array2 # [3, 2, 1, 4]

array3 = [3,2,1,4]
add_item3(5, array3)
p array3 # [3, 2, 1, 4]
require'set'
需要“基准”
def添加_项1!(项目、清单)
list不易混淆的术语是:传递原始对象(而不是副本/克隆/副本)。

通过共享调用的语义与通过引用调用的语义不同,因为调用方看不到函数中函数参数的赋值

在Ruby中,重新分配[local]参数对调用者没有影响,因为它不使用引用调用

在这个示例代码中,它显然没有引用调用语义;或者,第二种和第三种情况与第一种情况类似,它们分配回局部变量,但不修改原始对象

在“较低级别”上,实现是按值调用[引用]——也就是说,Ruby在内部使用指针等等——这就是为什么有时会使用重载短语“按引用调用”,而常常忘记了“按值”部分。。导致了这种混乱


def add_item1!(项目、清单)
#改变列表对象,它是传递的原始对象
#(没有发生复制/克隆/重复)

我看到的列表,我应该使用.replace来修改原始对象
def add_item1!(item, list)
  # MUTATES the list object, which is the original object passed
  # (there is no copy/clone/duplication that occurred)
  list << item unless list.include?(item)
end

def add_item2(item, list)
  # this creates a NEW list and re-assigns it to the parameter
  # re-assigning to a local parameter does not affect the caller
  # the original list object is not modified
  list |= [item]
end

def add_item3(item, list)
  set = Set.new(list)
  set << item
  # this creates a NEW list from set and re-assigns it to the parameter
  # re-assigning to a local parameter does not affect the caller
  # the original list object is not modified
  list = set.to_a
end