Ruby - 实例变量值自行改变

Ruby - Instance variable value changing by itself

我的代码中的一个实例变量一直在重新分配其值,尽管没有命令这样做。本质上,变量只被调用两次:一次,在启动时分配它的值,然后将它的值复制到另一个变量。我正在处理的代码对我来说有点复杂post,但这是一个基本的 运行down:

class Test
    def self.initialize
        @problem_var = [ ["1 2 3", "4 5 6"], ["a b c", "d e f"], ["bar", "foo"] ]
    end

    def self.main_method(parVar)
        data = @problem_var
        result = "Lorem"

        #Iterate through subarrays
        data.each do |dataBlock|

            #Some code here

            if condition then
                #The first subarray meets the condition

                char = dataBlock[1]

                #At this point char is equal to "4 5 6"
                #@problem_var still holds its original value of:
                # [ ["1 2 3", "4 5 6"], ["a b c", "d e f"], ["bar", "foo"] ]

                result = OtherModule.replace_six(char)

                #By this point, char is now equal to "4 5 7"
                #Curiously @problem_var is now equal to:
                # [ ["1 2 3, "4 5 7"], ["a b c", "d e f"], ["bar", "foo"] ]
            end
        end

        #More code here

        return result
    end 
end

result 赋值后,变量发生了一些奇怪的事情。此外,这似乎只发生一次,因此如果代码再次 运行 并将 7 更改为... 8,则 @problem_var 将不会更新。将 @problem_var 更改为常量无法阻止它被更改。在过去的两周里,我一直在考虑这个问题,但一直没能弄清楚。有人知道会发生什么吗?

编辑: 你们是对的!问题出在 OtherModule 中。我在接收 char 的参数变量上使用 gsub!。这是供将来参考的简化的 OtherModule 代码:

module OtherModule
    def replace_six(input)
        modified_string = "" 

        if condition(input) then
           #Input meets condition
           first_string = replace_numbers(input)

           #The following method doesn't really apply here
           second_string = replace_letters(first_string)

           modified_string = second_string
        end

        return modified_string
    end

    def replace_numbers(text)

        #Some code here

        #The following condition for numbers in `text`
        if condition(text) then
            text.gsub!("6", numberFunction)
            #numberFunction returns a string
        end
        return text
    end
end

问题最有可能出现在 OtherModule.replace_six。 如果它使用 String#replace 方法,那么,String 会发生变化,并且它的效果将在任何引用它的地方可见。


如果您无法访问 OtherModule 的代码,那么,请执行以下操作:

 result = OtherModule.replace_six(char.dup)

如果您有权访问 OtherModule 的代码,则更改 replace_six 的实现,使其使用 String#subString#gsub,因为它们 return 修改字符串的副本而不是改变原始字符串。