During a morning standup (less fun than actual standup) at work someone mentioned that a method was a good candidate for a refactor using Keyword Arguments. So I went back to my desk, googled it, and my newb brain said ‘Why?’.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
So above we’re looking at a method defined with your typical (positional) arguments and another method using required keyword arguments (defined by the colon following the argument name). It just looked like more typing to me. Maybe with a better error, so ok, there’s a point for that I guess.
Default arguments are defined just as you might expect:
1 2 3 4 5 6 7 8 9 10
But still, is there really much of an advantage? Readability is one way that keyword arguments might be a good way to go rather than positional arguments. If you were to encounter a method call in your codebase the keywords give you a clue as to what the arguments mean and maybe even how the argument are used within the method. Positional arguments would require you to go look up the method definition.
1 2 3 4
Beyond that, since in your are referencing the variable name contained in your method from your method call and assigning it a value for that method call, the order of the arguments does not matter.
1 2 3 4 5 6 7
To do something similar without keyword arguments would require passing a hash as an argument:
1 2 3 4 5 6
Giving that method default arguments might look something like:
1 2 3 4 5 6 7 8 9 10 11 12 13
So why not just use keyword arguments at that point and skip the curly braces, square brackets, and ‘.fetch’-es?
What really sold me is this:
When one Ruby method has to know the correct order of another method’s positional arguments, we end up with connascence of position.
If we decide to change the order of the parameters to mysterious_total, we must change all callers of that method accordingly. Not only that, but our mental model of how to use this method must change as well, which isn’t as simple as a find/replace.
This statement gave me two thoughts:
1. I haven’t been programming for long, but I’ve learned enough to know that it’s easier to build a clean interface once than to modify every call to a method when its implementation changes. When, not if.
2. More than that, if you are calling a method from another method or interacting with another object, with positional arguments that method or object now needs to know something about the order of arguments passed to the original method. It’s like it gets a little peak into the internal of the first method which doesn’t feel very encapsulated to me.
1 2 3 4 5 6 7 8 9 10 11 12