在Ruby中设置常数变量(不会修改)



我的代码有问题

def foo 
   var_original = var
   while something
     answer = modify! var #here we modify var in while loop
   end
   print var_original
   answer
end

//var_original是我的代码中的矩阵对象

var_original 以某种方式返回 var 的值,即使分配后从未调用过它的功能。

我的目标是让var等于返回answer之前的开始。我想做var = var_original,但只是意识到var_original也以某种方式完全没有理由发生了变化。

有了这个问题,我提出了一个问题,我是否可以设置var_original以锁定进行修改。我在论坛上使用$ global_variables找到了答案,但是在我将var_original变成$var_original后,它们没有解决我的问题。

还有其他可能的解决方案可以锁定var_original进行修改吗?这是我的代码(很确定整个部分不是真正需要的,只是要证明我在其他任何地方都不会调用original_map(。

def solve(minemap, miner, exit)
    original_map = minemap
    origins = miner
    list = []
    while true
        break if miner == exit
        if minemap[miner["x"]][miner["y"]].class == TrueClass
            possibles = find_possibles(minemap, miner)
            minemap[miner["x"]][miner["y"]] = [true, nil, possibles]
        elsif minemap[miner["x"]][miner["y"]].class == Array
            if minemap[miner["x"]][miner["y"]][1] == nil
                miner = charge!(minemap, miner, list)
            else
                temp_miner = miner
                teleport?(minemap, miner, list)
                if temp_miner == miner && minemap[miner["x"]][miner["y"]][2] == 0
                    minemap[miner["x"]][miner["y"]] = false
                end
            end
        else
            miner = origins
        end
    end
    print original_map #Prints minemap, but it should be original_map (crying)
    puts
    list
end
def find_possibles(minemap, miner)
    possibles = []
    if !minemap[miner["x"]][miner["y"] + 1].nil?
        possibles << "down"  if minemap[miner["x"]][miner["y"] + 1] == true && miner["y"] + 1 < minemap.size
    end
    if !minemap[miner["x"]][miner["y"] - 1].nil?
        possibles << "up" if minemap[miner["x"]][miner["y"] - 1] == true && miner["y"] - 1 >= 0
    end
    if !minemap[miner["x"] - 1].nil?
        possibles << "left" if minemap[miner["x"] - 1][miner["y"]] == true && miner["x"] - 1 >= 0
    end
    if !minemap[miner["x"] + 1].nil?
        possibles << "right" if minemap[miner["x"] + 1][miner["y"]] == true && miner["x"] + 1 < minemap.size
    end
    possibles
end
def charge!(minemap, miner, list)
    temp = minemap[miner["x"]][miner["y"]][2].shift
    list << temp
    minemap[miner["x"]][miner["y"]][1] = temp
    case temp
        when "down"
            miner["y"] += 1
        when "up"
            miner["y"] -= 1
        when "right"
            miner["x"] += 1
        when "left"
            miner["x"] -= 1
    end
    miner
end
def teleport?(minemap, miner, list)
    temp = minemap[miner["x"]][miner["y"]][1]
    list << temp
    case temp
        when "right"
            return miner if minemap[miner["x"]][miner["y"] + 1] == false
            miner["x"] += 1 if minemap[miner["x"]][miner["y"] + 1][2].size > 0
        when "left"
            return miner if minemap[miner["x"]][miner["y"] - 1] == false
            miner["x"] -= 1 if minemap[miner["x"]][miner["y"] - 1][2].size > 0
        when "up"
            return miner if minemap[miner["x"] - 1][miner["y"]] == false
            miner["y"] -= 1 if minemap[miner["x"] - 1][miner["y"]][2].size > 0
        when "down"
            return miner if minemap[miner["x"] + 1][miner["y"]] == false
            miner["y"] += 1 if minemap[miner["x"] + 1][miner["y"]][2].size > 0
    end
    miner
end
minemap = [[true, false],
    [true, true]]
puts solve(minemap, {'x'=>0,'y'=>0}, {'x'=>1,'y'=>0}) #== ['right']

就像我在评论中提到的那样,您将希望var_original成为var的深副本。例如,您将执行以下操作:

var_original = Marshal.load(Marshal.dump(var))

这样,每当您更改var时,var_original都不会更改。

您的心理模型中缺少一件事。var不是对象。它是对象的参考

 var_original = var

使var_original指向var指向的内存中相同对象。由于现在可以通过任何一个引用访问该对象,因此,如果您通过var更改它,则可以通过var_original看到更改。您想要的称为"深层复制/克隆"。查找。

或简单地做

var_original = var.dup

很可能会起作用。

最新更新