2

After calling delete_at on one of the arrays in my program, it alters another array at the same time. These two arrays have the same values, but should be handled as two separate things (altering one should not alter another).

Please note, I fixed the solution by using arr = arr[0..-2] instead of arr.delete_at(-1). I just want to know why the delete_at changed both arrays.

Also note that I know that this is probably not the best solution to the puzzle at hand, but that's not what we're talking about here ;)

def stock_picker(prices)
#takes an array of stock prices by day and returns the best day to buy and sell

#this solution starts at the last day and finds the greatest difference, then drops the last day and does it again 
#until there is just one day left.
def pick(all_prices, current_prices, current_pick)
    if current_prices == 1
        return current_pick
    else

        new_pick = tryer(all_prices, current_prices, [0, current_prices.size-1])

        puts "all_prices"
        puts all_prices

        if (all_prices[new_pick.last] - all_prices[new_pick.first]) > (all_prices[current_pick.last] - all_prices[current_pick.first])
            current_pick = new_pick
        end

        current_prices.delete_at(-1)
        #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#
        puts "After current_prices.delete_at(-1)"
        puts "all_prices"
        puts all_prices
        puts "current_prices"
        puts current_prices
        puts "wtf"
        return pick(all_prices, current_prices, current_pick)
    end
end

def tryer(all_prices, tryer_prices, tryer_pick)
    #subtracts the last day from each day.

    if tryer_prices.size == 1
        return tryer_pick
    else
        #the new pick reflects the first and last of the tryer_prices.
        new_pick = [tryer_pick.first + 1, tryer_pick.last]

        if (tryer_prices.last - tryer_prices.first) > (all_prices[tryer_pick.last] - all_prices[tryer_pick.first])

         return tryer(all_prices, tryer_prices.drop(1), new_pick)
        else
          return tryer(all_prices, tryer_prices.drop(1), tryer_pick)
        end

    end

end

all_prices = prices
current_prices = prices
pick(all_prices, current_prices, [0, prices.size-1])

end

result = stock_picker([17,3,6,9,15,8,6,1,10])
puts result

2 Answers 2

2

both variables reference to the same object in memory. Array#delete_at method mutates your array, so old variables reference to old array which was mutated.

On the other hand arr = arr[0..-2] does NOT mutate the array, it returns new one and assigns arr local variable to the result. That's why other references are not changed.

If you want to create duplicate of your original array you can use Object#dup method.

P.S. in Ruby method params are passed by reference, not by value.

Sign up to request clarification or add additional context in comments.

2 Comments

does ruby do this for all datatypes? Is it safe to assume I should avoid that type of variable assignment in programming generally? The only reason I ask is because I always thought var1 = var2 just copied the value into var1. Is this true for some but not all data types? Or am I way off base
Yes it does. In Ruby you have to explicitly use dup or clone if you want to copy an object.
1

The two arrays all_prices and current_prices are both just pointers at the original array prices. To make them separate copies, you might try the following:

all_prices = prices.clone
current_prices = prices.clone

Disclaimer: I've never used Ruby, but this is a common problem in many different languages. So I might not be using the clone method correctly (maybe dup would be better?), but the approach is correct: Make standalone copies of the original array, so changes to one won't affect the other.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.