From fbb178d5ac13c3f67e53ca413d44c16a3f4775d1 Mon Sep 17 00:00:00 2001 From: Juerd Waalboer Date: Mon, 18 Sep 2023 01:31:13 +0200 Subject: [PATCH] Formal mechanism for retrying input This allows for alias plugins with better error messages and better logging than with the $_[2] =~ s/// hack. --- lib/RevBank/Global.pm | 1 + lib/RevBank/Messages.pm | 9 +++++++-- revbank | 14 +++++++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/RevBank/Global.pm b/lib/RevBank/Global.pm index 26d28b2..05439c8 100644 --- a/lib/RevBank/Global.pm +++ b/lib/RevBank/Global.pm @@ -18,6 +18,7 @@ sub import { *{"$caller\::REJECT"} = sub () { \3 }; *{"$caller\::NEXT"} = sub () { \4 }; *{"$caller\::DONE"} = sub () { \5 }; + *{"$caller\::REDO"} = sub () { \6 }; *{"$caller\::slurp"} = \&RevBank::FileIO::slurp; *{"$caller\::spurt"} = \&RevBank::FileIO::spurt; *{"$caller\::rewrite"} = \&RevBank::FileIO::rewrite; diff --git a/lib/RevBank/Messages.pm b/lib/RevBank/Messages.pm index 923910c..38b59d8 100644 --- a/lib/RevBank/Messages.pm +++ b/lib/RevBank/Messages.pm @@ -45,8 +45,13 @@ sub hook_abort($class, $cart, @) { say "\e[1;4mABORTING TRANSACTION.\e[0m"; } -sub hook_invalid_input($class, $cart, $word, @) { - say "$word: No such product, user, or command."; +sub hook_invalid_input($class, $cart, $origword, $lastword, $allwords, @) { + say "$origword: No such product, user, or command."; + my @other = splice @$allwords, 1; + if (@other) { + $other[-1] =~ s/^/ and / if @other > 1; + say "(Also tried as " . join(@other > 2 ? ", " : "", @other) . ".)"; + } } sub hook_reject($class, $plugin, $reason, $abort, @) { diff --git a/revbank b/revbank index 2634ff1..07ef6e9 100755 --- a/revbank +++ b/revbank @@ -200,9 +200,10 @@ OUTER: for (;;) { abort if grep $_ eq 'abort', @words; my $origword = my $word = shift @words; + my @allwords = ($origword); push @retry, $word; - PLUGIN: for my $plugin (@plugins) { + ALL_PLUGINS: { PLUGIN: for my $plugin (@plugins) { my ($rv, @rvargs) = eval { $plugin->$method($cart, $word) }; if ($@) { call_hooks "plugin_fail", $plugin->id, $@; @@ -225,6 +226,13 @@ OUTER: for (;;) { if ($rv == ABORT) { abort(@rvargs); } + if ($rv == REDO) { + $word = $rvargs[0]; + call_hooks "redo", $plugin->id, $origword, $word; + push @allwords, $word; + + redo ALL_PLUGINS; + } if ($rv == REJECT) { my ($reason) = @rvargs; #abort if @words; @@ -253,11 +261,11 @@ OUTER: for (;;) { call_hooks "plugin_fail", $plugin->id, "Invalid return value"; abort; } - call_hooks "invalid_input", $cart, $origword, $word; + call_hooks "invalid_input", $cart, $origword, $word, \@allwords; @retry = (); abort if @words; redo OUTER; - } + } } } }