if tools_info.size > 3
print “\nbefore delete:\n”
puts “tools_info_array:\n”, tools_info_array
tools_info.slice!(0…2)
print “\nafter delete:\n”
puts “tools_info_array:\n”, tools_info_array
end
tools_info.each do |xsub|
…
end
#################################
2. run case1.rb get results below
#################################
before delete:
tools_info_array:
{“tool_a”=>[“tool_a_home”, “2009.12-17”, “bin”,
{“LD_LIBRARY_PATH”=>“lib”}]}
after delete:
tools_info_array:
{“tool_a”=>[{“LD_LIBRARY_PATH”=>“lib”}]}
#################################
3. my question
#################################
Why modify ‘tools_info’ cause ‘tools_info_array’ changed?
Define a temp variable to save tools_info as below can avoid issue, but
is there other method can avoid using temp variable, that get
‘tools_info’ modified but without influence on ‘tools_info_array’?
tools_info_tmp = tools_info.slice(3…-1)
tools_info_tmp.each do |xsub|
…
end
You can duplicate objects with the #dup method. This creates a copy
without introducing a temporary variable. The normal assignment
operation just copies a reference, so in your code tools_info refers to
the same object instance and not a copy. (Also, I think #clone is an
alias of #dup.)
Another way to handle it is to use #slice instead of #slice! as follows:
tools_info = tools_info.slice(0…2)
This allows the slice method to do the duplication as well as the
slicing.
One way to define bang and non-bang method pairs is to make the safe
method duplicate the arguments of the unsafe (bang!) method:
def some_method!(some_object)
# do something dangerous to some_object here
end
def some_method(some_object)
some_method!(some_object.dup)
end
As you can see, some_method does the exact same thing as some_method!,
but on a duplicate of the original object. This is an implicit way of
the explicit #dup I described before:
tools_info = tools_info_array[toolName].dup
I suppose it depends on the desired level of code, memory, and
processing complexity desired.
Thanks for your help check this issue, now I understand, in ruby, the
default behavior of the array variable is a reference(or name it as a
pointer) to the array(even slice of array), so any change on the contect
of slice will cause the original array value changed, the safe way is
dupicate the slice, or just move the pointer to the start of the slice
data, am I right?
Thanks a lot,
Previn
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.