The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

String::Switches - functions for parsing /switches and similarly constructed strings

VERSION

version 0.001

SYNOPSIS

  use String::Switches qw( parse_switches );

  my ($switches, $err) = parse_switches($user_input);

  die $err if $err;

  for my $switch (@$switches) {
    my ($name, $value) = @$switch;
    say "/$name = $value";
  }

PERL VERSION

This module should work on any version of perl still receiving updates from the Perl 5 Porters. This means it should work on any version of perl released in the last two to three years. (That is, if the most recently released version is v5.40, then this module should work on both v5.40 and v5.38.)

Although it may work on older versions of perl, no guarantee is made that the minimum required version will not be increased. The version may be increased for any reason, and there is no promise that patches will be accepted to lower the minimum required perl.

FUNCTIONS

parse_switches

  my ($switches, $err) = parse_switches($user_input);

This expects a string of "switches", something like you might pass to a program in the DOS terminal on Windows. It was created to parse commands given to a chatbot, and so has some quirks based on that origin.

The input should be a sequence of switches, like /switch, each one optionally followed by arguments. So, for example:

  /coffee /milk soy /brand "Blind Tiger" /temp hot /sugar /syrup ginger vanilla

The return is either ($switches, undef) or (undef, $error) If parsing fails, the error will be a string describing what happened. This string may change in the future. Do not rely on its exact contents.

If parsing succeeds, $switches will be a reference to an array, each element of which will also be a reference to an array. Each of the inner arrays is in the form:

  ($command, @args)

The example above, then, would be parsed into a $switches like this:

  [
    [ "coffee" ],
    [ "milk",  "soy" ],
    [ "brand", "Blind Tiger" ],
    [ "temp",  "hot",
    [ "sugar" ],
    [ "syrup", "ginger", "vanilla" ],
  ]

Multiple non-switches after a switch become multiple arguments. To make them one argument, use double quotes. In addition to ASCII double quotes, "smart quotes" work, to cope with systems that automatically smarten quotes.

parse_colonstrings

  my $hunks = parse_colonstrings($input_text, \%arg);

Achtung! The interface to this function may change a bit in the future, to make it act more like the switch parser, and to make it easier to get a simple fallback.

Like parse_switches, this is intended to parse user input into a useful structure. Instead of /switch-like input, it expects the sort of thing you might type into a search bar, like:

  best "thanksgiving recipe" type:pie

You can provide the fallback argument in %arg, which should be a reference to a subroutine. When a hunk of input is reached that doesn't look like key:value, the fallback callback is called, and passed a reference to the string being parsed. It's expected to modify that string in place to remove whatever it consumes, and then return a value to put into the returned arrayref.

If that sounds confusing, consider passing literal, instead. The value should be a name to be used as the key when a no-key hunk of text is found.

For example, given this code:

  my $hunks = parse_colonstrings(
    q{foo:bar baz quux:"Trail Mix"},
    { literal => 'other' },
  );

The result is:

  [
    [ foo     => 'bar' ],
    [ other   => 'baz' ],
    [ quux    => 'Trail Mix' ],
  ]

Like parse_switches, smart quotes work.

canonicalize_names

  canonicalize_names($switches, \%aliases);

This function takes the $switches result of parse_switches and canonicalizes names. The passed switches structure is altered in place.

Every switch name is fold-cased. Further, if $aliases is given and has an entry for the fold-cased switch name, the value is used instead. So for example:

  my ($switches)  = parse_switches("/urgency high");
  canonicalize_names($switches, { urgency => 'priority' });

At the end of the code above, $switches contains:

  [
    [ "priority", "high" ],
  ]

AUTHOR

Ricardo SIGNES <cpan@semiotic.systems>

CONTRIBUTOR

Ricardo Signes <rjbs@semiotic.systems>

COPYRIGHT AND LICENSE

This software is copyright (c) 2023 by Ricardo SIGNES.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.