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.