2014-01-29 2 views
0

Может кто-то объяснит мне, почему массив срез или сдвиг возвращает разные результаты, чем args -= [args.frist]рубин сдвиг и срез с проблемой рекурсии

Я хочу вывести [[1, 2, 3], [2, 3], [3], []].

def run(args=[1,2,3],results=[]) 
    results << args 
    return results if args.size < 1 
    args -= [args.first] 
    run(args,results) 
end 

VS.

def run(args=[1,2,3],results=[]) 
    results << args 
    return results if args.size < 1 
    args.shift 
    run(args,results) 
end 

ответ

0

Потому что все args ссылаются на тот же массив.

Чтобы избежать этого, не изменяйте args.

Вместо этого сделайте копию:

def run(args=[1,2,3],results=[]) 
    results << args 
    return results if args.size < 1 
    run(args[1..-1], results) 
end 
1

Рубин передача по значению. Но объекты на самом деле являются ссылками. Позволь мне объяснить. Когда вы делаете:

s = 'abc' 
s1 = s 
s1.gsub! /a/, 'A' 
puts s 
# ⇒ 'Abc' 

, если вы dup объект, все ссылки не будут указывать на то же, скажем, блок памяти. Вот почему у вас второй пример: args изменен не только сам, но и внутри массива results.

Линия

args -= [args.first] 

фактически не изменяет массив заданного в качестве параметра, хотя. Он объявляет новую локальную переменную и меняет ее. Ссылки на уже введенные значения results остаются такими, какими они были.

run args.dup.shift, result 

будет делать трюк.

+0

Это объясняет много. Я потратил слишком много времени, пытаясь понять, почему результат не синхронизирован. – alexzg

Смежные вопросы