Home > Uncategorized > Keys are optional

Keys are optional

On my quest to a concurrent File::Find I found the need to have arguments (in this case as Bool) that are of a group of sorts and are mutual exclusive. Enums are very groupy, introduce easy to use names into the scope (directly or via is export) and should be easy to make mutual exclusive. The easy part was a bit naive because typed slurpy arguments are not supported (yet). If there is no easy way, there must be a hard way that is possible.

First let’s define two enums that serve as options to find.

package Find {
  enum Type (<File Dir Symlink>);
  enum Options (<Recursive Keep-going>);

Now we can have a where-clause that first checks if all members of a slurpy array are either of type Find::Type or Find::Options. Then we can check how many elements of Find::Options there are. Since there can be only one we complain about exclusiveness if there are to many.

+@options where {
  @options.all (elem) (Find::Type::.values (|) Find::Options::.values)
  && (+(@options.grep: * ~~ Find::Type) <= 1 or die "can only check for one type at a time")

In the body of the routine we can use junctions and smart matching to check if options are present.

my Bool $recursive = any(@options) ~~ Find::Recursive;
my %tests = Find::File => {so .f}, Find::Dir => {so .d}, Find::Symlink => {so .l};
@tests.append(%tests{@options.grep: * ~~ Find::Type});

The routine is then called with a list of flags at the end of it’s parameter list.

find(%*ENV<HOME>, include => {.extension eq 'txt'}, exclude => ['cfg', /.xml $/] , Find::File, Find::Recursive, Find::Keep-going);

The same would be possible to do with named arguments but I can’t see a way to do the exclusiveness in a where-clause. I like to have as much argument processing in the signature because it makes it easy to write documentation. Separate all arguments with a newline and then translate type constraints and where-clauses into plain English. Also, having enums as flags feels quite 6-ish and that’s what this blog (post) is about.

Categories: Uncategorized
  1. No comments yet.
  1. September 26, 2016 at 23:05

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: