This new module could even go in a separate gem – and with its own dependencies! Organizing things this way is called the adapter design pattern. Let’s look at a few examples of this pattern in the wild.

multi_json

A good example is the multi_json gem which parses JSON with the fastest available backend. In multi_json, each backend is contained in an class that descends from Adapter. Here’s multi_json/lib/multi_json/adapters/gson.rb.

Here, load executes each library’s method for turning a JSON string into an object, and dump executes the method for turning an object into a string.

ActiveRecord

ActiveRecord is Rails’ ORM library for interacting with relational databases. It relies on the adapter pattern to allow the developer to interact with any supported database using the same methods. We can find this pattern in ActiveRecord‘s connection_adapters.

Dependencies

Ruby 2.3 adds the new squiggly heredoc syntax which will be useful in this case as it prevents unnecessary leading whitespace. Adding it to the Gemfile will not install it. It will need to be installed separately with a command like (if you use RVM):

::adapter sets a default adapter the first time it is called. Notice that adapters are not loaded until they are set. This avoids exposing developers to bugs in unused adapters and allows adapters in the same project to use their own dependencies without requiring all dependencies for all adapters up front.

The Adapters

The first adapter parses using the scan method with an appropriate regular expression. The regex delimiter searches for either anything that is not a comma or two consecutive commas:

Test Helper

The main thing that needs to be done here is setting up the minitest dependencies, and we can go ahead and load the project code as well. This is not really a necessary file here, but it’s common in larger projects.

Conclusion

Adapters are great ways to incorporate multiple ways of accomplishing something without resorting to mountains of conditional branching. They also let you split approaches into separate libraries that can have their own dependencies. If adapters are loaded in a lazy manner, broken adapters will not affect a project unless they are used.