Here are some tidbits I found trying to break default arguments in Ruby.
Look at this:
def foo(biz=:biz, bar=:bar, bazz) [biz, bar, bazz] end
You can pass optional arguments before required ones. Why would you be able to do this? Well...
irb> foo ArgumentError: wrong number of arguments (0 for 1)
The arity of the function is 1?
irb> method(:foo).arity => -2
Looks like it. (
-n-1 when optional arguments exist, where
n is the number of required arguments.)
How do we use
foo? We can pass it all optional and required arguments, and it will behave as you'd (probably) expect:
irb> foo(:test, :my, :method) => [:test, :my, :method]
If we pass one argument, it replaces the first optional argument:
irb> foo(:howdy) => [:biz, :bar, :howdy]
If we pass two arguments, it'll replace the first (and only) optional argument, then the first required argument:
foo(:howdy, :partner) => [:howdy, :bar, :partner]
When would this be useful? I'm not sure.
It seems that either all optional arguments must come before all required arguments, or vice versa. The following breaks:
irb> def so(long=:and, thanks=:for, all, the=:fish) irb> end SyntaxError: (irb):17: syntax error, unexpected '=', expecting ')'
By the way, you can pass default arguments in a
Object.send(:define_method, :bar) do |bizz=:bizz, baz=:baz, buzz=:buzz| end
However, it reports the wrong arity:
irb> method(:bar).arity 0
Which I've opened an issue for https://bugs.ruby-lang.org/issues/8411