Easy to use variable lenght input parser mechanism that provides a convenient and advanced way to enchance your custom function parameter handling.
What would you do in a situation, when you want to use a third party function or library, but the only documentation is a usage example?
% use this function to generate a sine wave
ssin(440, 2, 45, 48e3, 0.8)
Well, unless you are desperate enough to delve into the source code to figure out which parameter is which this function is pretty useless for you.
It would be much more useful, if there would be a built in guide that is self-explanatory. Do you prefer this way instead?
ssin('f', 440, 'A', 2, 'phi', 45, 'fs', 48e3, 'L', 0.8)
You know exactly what you are going to do in this case. You type a bit more, but the function call is self-explanatory for everyone else, and this is exactly what Simple Input Parser provides for you in the first place. This mode is called key-value pair mode.
But. If you want to use this function, you will have to remember the exact order of the parameters. If a function has more than 4 or 5 parameters you will have a hard time remembering what goes to another. What if there would be no parameter order constrain at all? With Simple Input Parser you can pass your key-value pairs in any order you like.
How about writing less apostrophes?
ssin('A f L fs phi', 2, 440, 0.8, 48e3, 45)
This is the bulk mode of Simple Input Parser. You write the keys first as a string, and the values in the order you have specified before. Same self-explanatory function call with less apostrophes and commas to write.
How about this function call?
ssin('AfLfsphi', 2, 440, 0.8, 48e3, 45)
Well, this is still the bulk mode and it is completely valid with Simple Input Parser. A little less self-explanatory, bat it is incredible fast to write. Feel free to use it whenever you want.
We have discussed the first three features of Simple Input Parser which would be useful for the users that are using the functions equipped with Simple Input Parser, but there are another three very useful features for the developers as well.
For the users | For the developers |
---|---|
1. Arbitrary parameter order | 4. Extra flag mode |
2. Key value pair mode | 5. Automatic parameter validation by type |
3. Bulk mode | 6. Custom validator functions with custom error messages |
Before we go into the details of the final three featurea, you have to install Simple Input Parser.
In the latest release page you can find the MLS package containing Simple Input Parser. This method provides a simple and easy installation.
- Download and unpack the latest release into your machine.
- Navigate into the unpacked folder and run the
install
command or open up and run theinstall.m
script. - Done. Now you have Simple Input Parser on your system.
MLS packages are powered by the MATLAB Library System. Go to that link to find out more about this systemIt's a good practice to keep all your MLS packages in a common folder and use the install_all.m script to install all your packages at once.
If you are not interested in the MLS package system, you can still download the pure Simple Input Parser source files, and you can install/include them manually anywhere you want.
Let's say you want to write a function with Simple Input Parser that expects three parameters: a
, b
, c
. Your can write this function in the usual way except three things:
- You have to use varargin for the parameter list.
- You have to create a parameter structure that will contain your parameters and its default values.
- You have to call the
simple_input_parser()
api function with the parameter structure and the varargin parameter, and use the previously created parameter structure for the output parameter.
function ret = my_function(varargin)
params.a = 42;
params.b = 'answer';
params.c = 55.3;
params = simple_input_parser(params, varargin);
% further functionalities that uses the params struct
end
Congratulation! With these three simple modifications you have implemented four features from the six Simple Input Parser features!
To name this four features:
my_function()
can accept it's parameters in an arbitrary order- It will support the key-value pair mode..
- ..as well as the bulk mode. Mode selection is automatic.
- It will perform an automatic parameter type validation, since you have implicitly defined your parameter's types.
The simple_input_parser()
function will return with the modified parameter structure. If the user did not passed the parameter, the default value will be left in there that you have specified earlier.
In some situations it might be useful to know, what parameters were passed to your function. Of course, you can compare the returned structure to the one with the default values, but Simple Input Parser offers an easier one.
You can call the simple_input_parser()
function with two input parameters. The first one is the output parameter structure and the second one is the flag structure. This mode is called Extra flag mode.
function ret = my_function(varargin)
params.a = 0;
params.b = 0;
params.c = 0;
[params, flags] = simple_input_parser(params, varargin);
if flags.b
disp('b parameter was passed');
end
% further functionalities
end
If a value was parsed, it's corresponding field in the flags structure will be assigned to one. It provides you a convenient way to handle custom cases that are depend on the passed parameters.
Simple Input Parser provides an interface to easily create custom validator functions. If the default automatic type based validation isn't enough for you, you can use more specific validator functions for each parameters if you want. For this purpose you have to create a nested validator function with a fix signature:
function [validflag, errormsg] = my_validator_for_the_parameter_c(value)
validflag = value > 1;
errormsg = 'Parameter c has to be greater than 1..';
end
Input |
---|
value - Parameter value that passed to the function. |
Output |
---|
validflag - Validation result. It is true if the parameter passed the validation. |
errormsg - Message that will be displayed if the validation fails. |
You can use any logic you want to generate the validation result (validflag) and the custom error message (errormsg) based on the given parameter value (value).
To specify which validator function belongs to which parameter, you need to create a structure with fields identical to the parameters you want to validate, assigning a pointer pointing to the validator function. Simple Input Parser will call this validator function with the parameter's value if it parses the specified parameter, and based on the returned value (validflag) it will throw an error with the specified error message (errormsg).
The custom validation is optional, so you don't need to specify a validator function for each parameters. If a parameter doesn't has a validator function the default automatic type based validation will be used for that parameter.
function ret = my_function(varargin)
params.a = 0;
params.b = 0;
params.c = 0;
function [validflag, errormsg] = my_validator_for_the_parameter_c(value)
validflag = value > 1;
errormsg = 'Parameter c has to be greater than 1..';
end
validators.c = @validate_c;
params = simple_input_parser(params, varargin, validators);
% further functionalities
end
You can use one validator function for more than one parameters, but keep in mind that you will get only a value without any information for the parameter name.
There is a parameter called RETHROW_EXCEPTIONS
that you can edit in the simple_input_parser.m
file. This variable allows you to control the library's behavior in case of error. Simple Input Parser has two error handling modes:
RETHROW_EXCEPTIONS |
In case of an error simple_input_parser() .. |
---|---|
true | will throw an exception. |
false | will stop the execution and print out the error. |
The default value is false, so in case of an error, the simple_input_parser()
function will gently stop the execution, and it will display the default error messages shipped with Simple Input Parser.
If you want to display your own error messages for the error cases, you can use custom validator functions and/or you can turn on the RETHROW_EXCEPTIONS
flag inside the simple_input_parser.m
file, and catch the exceptions that simple_input_parser()
function throws to you.
Since MATLAB's exception system uses exception identifiers instead of exception classes and subclasses, Simple Input Parser uses the following exception format for the exception identifier:
component:mnemonic = SimpleInputParser:exceptionId
exceptionId | Error case |
---|---|
invalidParameterLength | There were less than 2 or there were more than enough parameters passed to the function. |
invalidKey | The parsed key is invalid since no matching parameter was found. |
redundantKey | A key passed two times. |
unusedValue | There were more values than keys specified. |
typeError | A parsed value didn't passed the automatic type based validation. |
validationError | A parsed value didn't passed the corresponding custom validatior function. |
If you want to contribute to this project you have to make sure, that your contribution don't violates the test harness located in the test
folder of each port.
If a pull request fails any of the tests, the request will be automatically invalidated.
The current MATLAB port contains 33 tests:
Running SimpleInputParserTests
..........
..........
..........
...
Done SimpleInputParserTests
__________
result
_________________________________
[1x33 matlab.unittest.TestResult]
This project is under the MIT license. See the included license file for further details.