So it's syntactic sugar? What a shame. The whole point is having the language handle it so its default behavior is well-known and uniform and not implement umpteenth patterns and validations[0].
Well, it does actually define locals. But, IIRC, it uses the symbol hash parsing productions, so the default values are required. The only way to specify required parameters (without the above hacks) is to do a traditional method definition:
irb(main):001:0> def foo(bar, baz: Object.new); [bar, baz]; end
=> nil
irb(main):002:0> foo(1)
=> [1, #<Object:0x007fbc39161ed8>]
irb(main):003:0> foo(1, baz: 10)
=> [1, 10]
irb(main):004:0> foo(baz: 10)
ArgumentError: wrong number of arguments (0 for 1)
from (irb):1:in `foo'
from (irb):4
from /Users/aaron/.local/bin/irb:12:in `<main>'
irb(main):005:0>
[0] e.g assert_valid_keys (raising ArgumentError on a mismatch so it's really only for options={} pattern: http://api.rubyonrails.org/classes/Hash.html#method-i-assert...