Why `include Dry::Types.module`?

I’m new to DryRB and wanting to get up to speed on some of the design decisions. The first thing that jumped out at me was the way you use Dry::Types.

As Dry::Types is a module, I’d expect to just

include Dry::Types

but instead we should use

include Dry::Types.module

The #define_constants method in the source code wasn’t super obvious to me, but it would seem that #module is just instantiating an anonymous module and #define_constants is dynamically assigning all the relevant stuff from Dry into it.

Why do it this way?

I can guess that the reason is something like, every time you include this you get a vanilla “copy” of Dry::Types that can’t have been monkey patched. Is that really all there is to it, or is there some more interesting benefit?

This is just not something we ordinarily see in rubyland so I was curious if I understood what it’s doing and would love to hear what the rationale was :slight_smile:

Thanks for the help!

Main reason is that you get types defined as constants within your namespaces and nothing else. If we put them under Dry::Types and include it in another module, then you’d get the rest of the library constants available too, which would pollute your namespace with things you don’t need. Another reason is that building a module dynamically is more flexible, ie in the future we may have additional features, like passing some configuration to module method which would adjust type settings in various ways etc.

1 Like