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

时间:2017-05-04 17:15:20

标签: 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']

2 个答案:

答案 0 :(得分:0)

你的心理模型中缺少一件事。 var不是对象。它是对象的引用

 var_original = var

这使得var_original指向内存中var指向的同一对象。由于现在可以通过任一引用访问该对象,因此如果您通过var进行更改,则会通过var_original查看更改。你想要什么称为&#34;深度复制/克隆&#34;。查一查。

答案 1 :(得分:0)

或者简单地说,做

var_original = var.dup

很可能会奏效。