Posted about 4 years ago. Visible to the public. Repeats. Linked content.

Ruby: Do not mix optional and keyword arguments

Writing ruby methods that accept both optional and keyword arguments is dangerous and should be avoided. This confusing behavior will be deprecated in Ruby 2.7 and removed in Ruby 3, but right now you need to know about the following caveats.

Consider the following method

Copy
# DO NOT DO THIS def colored_p(object = nil, color: 'red') switch_color_to(color) puts object.inspect end colored_p(['an array']) # ['an array'] (in red) colored_p({ a: 'hash' }, color: 'blue') # {:a=>'hash'} (in blue) colored_p({ a: 'hash' }) # ArgumentError: unknown keyword: a

What happened?

Ruby does not know whether to interpret this as

Copy
colored_p({ a: 'hash' }, color: 'red')

or as

Copy
colored_p(nil, a: 'hash')

It defaults to the later, and then throws an error.

Worse, this can also happens for any arguments that define to_hash, for example

Copy
class User attr_accessor :first_name, :last_name def to_hash { first_name: first_name, last_name: last_name } end end colored_p(User.new) # ArgumentError: unknown keywords: first_name, last_name

This behavior is not very smart.

The easy fix is just to never mix optional and keyword arguments in the first place, so there can never be any ambiguity.

Once an application no longer requires constant development, it needs periodic maintenance for stable and secure operation. makandra offers monthly maintenance contracts that let you focus on your business while we make sure the lights stay on.

Owner of this card:

Avatar
Tobias Kraze
Last edit:
17 days ago
by Besprechungs-PC
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Tobias Kraze to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more