Thank you Ruby 2. You're better than Python.
Like many, I am excited about Ruby 2's keyword parameters. It allows you to default arguments to your method like so:
def foo(x, y: 2)
p "#{x}, #{y}"
end
foo(1) #=> 1, 2
foo(2, 3) #=> 2, 3
foo(5, y: 9) # => 5, 9
This is a very natural way to write code without resorting to the old splat/hash techniques.
Python also has this functionality, but there is a subtle quirk that bit me in the ass really badly once. The default objects passed in are shared:
def foo(arr=[]):
arr.append('x')
print arr
foo() #=> ['x']
foo() #=> ['x', 'x']
foo() #=> ['x', 'x', 'x']
It's definitely subtle, but this really isn't how I would expect this code to work. I would expect the function to reset back to an empty array every time, not share it globally.
Thankfully, Ruby 2 acts the way I want it to:
def foo(arr: [])
arr << ('x')
print arr
end
foo() #=> ['x']
foo() #=> ['x']
foo() #=> ['x']
Written by dickeyxxx
Related protips
4 Responses
This is not a design flaw, it's a feature.
For this kind of situation you might consider this:
def foo(arr=None):
if arr is None:
arr = []
arr.append('x')
print(arr)
A little more verbose but still very readable :)
def foo(x,y=2):
print("%d,%d" % (x,y))
</code>
@doganaydin I don't think you read my post
Like @caioariede said, it's "feature". I often use this in my code, and find it very useful.