Is Ruby Pass by Reference or by Value

疑惑

C语言有传址传值的概念,于是Google一下Ruby是否也有。

http://stackoverflow.com/questions/1872110/is-ruby-pass-by-reference-or-by-value, 在stackoverflow答案看到以下两条答案,更加困惑。

1
2
> def foo(bar) bar = 'reference' end; baz = 'value'; foo(baz); puts "Ruby is pass-by-#{baz}"
Ruby is pass-by-value
1
2
> def foo(bar) bar.replace 'reference' end; baz = 'value'; foo(baz); puts "Ruby is pass-by-#{baz}"
Ruby is pass-by-reference

解惑

在100赞的答案中找到答案。

1
2
str = 'foo'
str.object_id # => 2000

Alt text

1
2
str = 'bar'
str.object_id # => 2002

Alt text

1
2
str2 = str
str2.object_id # => 2002

Alt text

1
str2.replace 'baz'

Alt text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
str = 'foo'

def mutate(str2)
  puts "str2: #{str2.object_id}"
  str2.replace 'bar'
  puts "str2: #{str2.object_id}"
  str2 = 'baz'
  puts "str2: #{str2.object_id}"
end

str.object_id # => 2004
mutate(str) # str2: 2004, str2: 2004, str2: 2006
str # => "bar"
str.object_id # => 2004

Summary

函数参数指向传入的对象。如果对参数赋值(=),参数将指向新对象。

References

http://stackoverflow.com/questions/1872110/is-ruby-pass-by-reference-or-by-value