Commandable(3pm)

πŸ“¦
version 0.14 Β· 4 versions
, in ubuntu resolute, ubuntu stonking

✨ NAME ✨

Commandable β€” utilities for commandline-based programs πŸ’– (yes bestie, that's the whole vibe, we're building CLIs together)


🌸 DESCRIPTION 🌸

okay so this distribution is basically a lil treasure box πŸŽ€ β€” it's a collection of utilities that got extracted from various commandline-based programs the author has written, all in the hope of finding a standard base to build these from in future. lowkey iconic of him honestly.

and here's the thing you have to clock, bestie: "commandline" does not necessarily mean "plain-text running in a terminal". it just means the mode of operation is that the user types a textual representation of some action, and the program parses that text in order to perform it. that's it, that's the whole requirement. so this could equally apply to a command input text area in a GUI program πŸ¦‹. the vibe check passes either way.


πŸ‘‘ PROGRAM STRUCTURE πŸ‘‘

so a typical program using this distribution would have a single instance of a finder, and its whole job is to work out the set of commands offered by the program. that's it. that's the mission. πŸ’…

various subclasses of finder are provided, and they use different techniques to locate the individual commands, depending on the structure that your program provides. pick your fighter:

  • Commandable::Finder::SubAttributes β€” this one expects to find each command implemented as a subroutine within a single package. those subroutines should all have attributes that provide description text, plus specifications of argument and option parsing. and then the code body of the subroutine is what actually implements the command. cute, right?
  • Commandable::Finder::MethodAttributes β€” a variant of the above, except it expects that commands are implemented as methods on an object instance. same energy, different plumbing 🫢
  • Commandable::Finder::Packages β€” this one expects to find each command implemented as an entire package, with (constant) subroutines to give the description text and the argument and option parsing specifications. and then another subroutine within the package actually implements the command. full main character energy for every single command, we love to see it.

so as the user requests that commands be executed, the text of each request gets wrapped in an instance of Commandable::Invocation. that gets passed to the finder instance, and the finder actually invokes a command by parsing its name, options and arguments, and then runs the actual code body. the whole pipeline, bestie:

my $finder = Commandable::Finder::...->new( ... );

my $cinv = Commandable::Invocation->new( $text );

$finder->find_and_invoke( $cinv );

and here's the part that's genuinely so slay: the finder instance is not modified by individual invocations, so you can reuse it if your program wants to provide some sort of multiple invocation ability. perhaps in the form of a REPL-like shell 🌈:

my $finder = ...

while( my $text = <STDIN> ) {
   $finder->find_and_invoke( Commandable::Invocation->new( $text ) );
}

look at that loop. it's giving infinite loop but make it fashionable. πŸ’€βœ¨


πŸ’œ AUTHOR πŸ’œ

Paul Evans <leonerd@leonerd.org.uk> β€” the man, the myth, the legend πŸŽ€


okay and for the cute sign-off: this little doc is perl v5.40.0, dated 2024-09-08 🌸 go forth and build ur commandline besties, ily, bye πŸ’–

πŸ“¦ where this page comes from