5ab5traction5 - World Wide and Wonderful

Introducing `Resource::Wrangler`

What

I've recently released a new Raku module called Resource::Wrangler. The idea is to provide a simple way to handle a pretty significant roadblock in the way Raku handles resources.

Why

Raku distributions have a %?RESOURCES variable that stores references to the resources that are declared in the resources object defined in META6.json.

However, complications arise even as early as testing. This is because the tests will be compiled outside of the CompUnit and it's the CompUnit that circumscribes the extent %?RESOURCES.

In other words, different CompUnit, different %?RESOURCES.

But even beyond that, something as seemingly straightforward as having a local copy of the resource to hand to a library can be quite convoluted.

Resource::Wrangler to the rescue

By combining Resource::Wrangler with dependency injection, it is now dead simple to bridge the gap between the distribution's CompUnit, code that makes use of that distribution's CompUnit, and the test files.

Resource::Wrangler utilizes role parameterization, a sort of hyper-flexible Raku-soaked take on implementing "generics" while adding a lot of characteristic spice to the possibility space.

Example: Resourceful

Here is an example directly from the test suite:

class Resourceful {
    has $.resources handles <AT-KEY> = 
		Resource::Wrangler[{ %?RESOURCES }].new;
}

The most sensible default for parameterizing Resource::Wrangler is { %?RESOURCES }, i.e. a block that returns the %?RESOURCES of the current CompUnit.

Resource::Wrangler implements AT-KEY to expose associative indexing to %?RESOURCES, allowing Resourceful to do the same by declaring that $.resources handles <AT-KEY>. This will be demonstrated in the example below.

But then when we go to test, we can set our own Str => IO pairs for Resource::Wrangler to reference:

my %resources = test => "/tmp/test".IO;
my $resourceful = Resourceful.new: 
			resources => Resource::Wrangler[-> { %resources }].new;
is "/tmp/test".IO, $resourceful<test>, "Dependency injection works as expected";

Note that the block here needs a signature so as not to be mistaken for a single-argument "hash from a hash" initialization by Raku's grammar. Since %?RESOURCES is actually an object rather than a "proper" hash, it doesn't need this special treatment.

More examples incoming

I wrote this library to address some obstacles in another project entirely, one which should have significant examples of relatively complex use of Resource::Wrangler.

Until then, thanks for reading.