I think you are focused on what's wrong here. I do such things with Data :: Constraint, Brick , etc. And talk about it in Mastering Perl. With a little ingenuity and thought about the structure of your program and the dynamic functions that Perl has, you do not need such a regulated procedural approach.
However, the first thing you need to find out is what you really want to know in this calling routine. If you just want to know yes or no, it's pretty easy.
The problem with your needs is that you think of invoking it once for each condition, which forces you to use needs to control the flow of the program. This is the wrong way. needs just to give you an answer. The task is not to change the state of the program. This becomes less useful if you abuse it, because some other calling routine may want to continue, even if needs returns false. Call once and let him return once. The calling routine uses the return value to decide what it should do.
The basic structure includes the table that you pass needs . This is your verification profile.
sub run_find {
my $ arg = shift @_;
return unless needs [
[sub {$ arg}, "arg required"],
[sub {exists $ lang {$ arg}}, "No such language: $ arg"],
];
}
...
}
You create a table for any of your requirements. In needs you just process the table:
sub needs($$) { my ($table) = @_; foreach $test ( @$table ) { my( $sub, $message ) = @$test; unless( $sub->(...) ) { print $message; return } } return 1; }
Now, the really cool thing with this approach is that you don't need to know the table in advance. You can pull this out of the configuration or in some other way. It also means that you can dynamically modify the table. Now your code is shortened a bit:
sub run_find {
my $ arg = shift @_;
return unless needs ($ validators {run_find});
...
}
You will continue with this. In Mastering Perl, I show a couple of solutions that completely remove this from the code and transfer it to the configuration file. That is, you can change business rules without changing the code.
Remember that almost at any time when you enter the same sequence of characters, you are probably mistaken. :)