Your assumption is wrong: ruby is not pass-by-reference, it is strictly pass-by-value, always. You can easily verify this by running this simple test:
def foo(bar)
bar = 'reference'
end
baz = 'value'
foo(baz)
puts "Ruby is pass-by-#{baz}"
# Ruby is pass-by-value
More precisely, Ruby is call-by-object-sharing (also known as call-by-object and call-by-sharing), which is a special case of pass-by-value, where the value that is passed is always a pointer to a (potentially) shared (potentially) mutable object:
def is_ruby_pass_by_value?(foo)
foo.replace('More precisely, it is call-by-object-sharing!')
foo = 'No, Ruby is pass-by-reference.'
end
bar = 'Yes, of course, Ruby *is* pass-by-value!'
is_ruby_pass_by_value?(bar)
p bar
# 'More precisely, it is call-by-object-sharing!'
However, that is actually irrelevant to your question. It has nothing to do with pass-by-reference vs. pass-by-value.
So inside testarray function, I have an array arr_tree
which is being passed to a function abcde
. I change the value of the array inside abcde
function and print array inside testarray
I get the changed value here.
You get the changed value because you change the value. It's as simple as that. Ruby is not a pure functional programming language, it does have mutable state. And if you mutate that state, then the old state is gone and only the new state exists.
You wrote yourself:
I change the value of the array
Well, if you change the array, the array changes! There is only one array in your entire code.
Please explain why the results are like this?
The array changes because you change the array.
Also how can I achieve my expected result?
You can achieve your result by not changing the array:
def testarray
arr_tree = [1, 2, 3, 4, 5]
(1..3).each do |index|
abcde(arr_tree)
puts arr_tree[0]
end
end
def abcde(node_tree)
[node_tree.first + 100, *node_tree.drop(1)]
end