3 ms·
I would hate to get an interview question where the very premise of it is wrong. Python does have mutable arguments, but so does Ruby. def func(arr=[])
by Spivak 3y ago
I would hate to get an interview question where the very premise of it is wrong. Python does have mutable arguments, but so does Ruby.
def func(arr=[])
# Look ma we mutated it.
arr.append 1
puts arr
end
Why calling this function a few times outputs [1], [1],... instead of [1], [1, 1],... isn't because Ruby somehow made the array immutable and hid it with copy-on-write or anything like that. It's because Ruby, unlike Python, has default expressions instead of default values. Whenever the default it needed Ruby reevaluates the expression in the scope of the function definition and assigns the result to the argument. If your default expression always returned the same object you would fall
into the same trap as Python.
The sibling comment is wrong too -- it is a local variable, or as much one as Python can have since all variables, local or not, are names.
- Jtsummers 3y agoJust as a demo of what you're saying: If you were to do (the following is from memory, probably has typos): def func(arr=[]): print(locals) You'd see `arr` there. The `[]` value lives in `func.__defaults__`: def func(arr=[]): print(locals) print(func.__defaults__) # will print: ([],) If you assign to `arr` nothing changes with defaults: def func(arr=[]): print(locals) arr = 10 print(func.__defaults__) # will still print: ([],) But since lists are mutable, calling a mutating function on the list referenced by `arr` will cause a mutation of the list stored in defaults: def func(arr=[]): print(locals) arr.append(10) print(func.__defaults__) # will print: ([10],) But only when `func` is called without something to assign to `arr`: # if pristine and it has not been run before def func(arr=[]): print(locals) arr.append(10) print(func.__defaults__) # will print: ([],) func([])