NAME
MOP4Import::Base::CLI_JSON - Base class for rapidly building testable CLI modules with JSON I/O
SYNOPSIS
#!/usr/bin/env perl
package MyScript;
use MOP4Import::Base::CLI_JSON -as_base,
[fields =>
[verbose => doc => "Enable verbose output", json_type => 'bool'],
[config => doc => "Config file path", json_type => 'string']
];
MY->cli_run(\@ARGV) unless caller;
# Official CLI command - handles its own output
sub cmd_status : Doc("Show system status") {
my ($self) = @_;
print "System OK\n";
}
# Regular method - output handled by CLI_JSON
sub query {
my ($self, $sql) = @_;
# Returns data structure that will be JSON-encoded
return {result => "data from $sql"};
}
1;
From shell:
# Show help
$ ./MyScript.pm --help
# Call official command
$ ./MyScript.pm status
System OK
# Call regular method (output as NDJSON by default)
$ ./MyScript.pm query "SELECT * FROM users"
{"result":"data from SELECT * FROM users"}
# Use different output format
$ ./MyScript.pm --output=yaml query "test"
---
result: data from test
# Pass complex data structures as arguments
$ ./MyScript.pm process '{"key":"value"}' '[1,2,3]'
DESCRIPTION
MOP4Import::Base::CLI_JSON enables rapid development of Perl modules by making any method immediately testable from the command line. It provides automatic JSON serialization for inputs and outputs, making it ideal for exploratory development and debugging.
Key features:
Instant CLI access to any module method
Automatic JSON encoding/decoding of arguments and return values
Multiple output formats (ndjson, json, yaml, tsv, dump, raw)
Direct integration with debugger (
perl -d
) and profilerType checking via
json_type
field declarations
For conceptual background, see OO Modulino Pattern.
USAGE
Creating a CLI_JSON Module
To create a module that can be used both as a library and CLI tool:
package MyModule;
use MOP4Import::Base::CLI_JSON -as_base;
MY->cli_run(\@ARGV) unless caller;
# Your methods here
1;
The unless caller
idiom ensures cli_run
only executes when the file is run directly, not when it's loaded as a module.
Command Resolution Rules
When invoked from CLI, the first argument is treated as the command name:
cmd_$COMMAND
-
If a method
cmd_$COMMAND
exists, it's treated as an official CLI command. The method is responsible for all output and exit handling. $COMMAND
-
If a method matching the command name exists, it's invoked and its return value is automatically serialized according to the
--output
option. - Unknown commands
-
If no matching method exists,
cli_unknown_subcommand
is called, which by default shows an error message and help.
Field Declarations
Fields can be declared with type information and documentation:
use MOP4Import::Base::CLI_JSON -as_base,
[fields =>
[dbfile =>
doc => "Database file path",
default => ":memory:",
json_type => 'string'
],
[limit =>
doc => "Result limit",
json_type => 'integer',
validator => sub { $_[0] > 0 }
]
];
Field Options
doc
-
Documentation string shown in help output
default
-
Default value for the field
json_type
-
JSON Schema type for validation. Supported types:
string
,bool
,boolean
,int
,integer
,number
validator
-
Code reference for custom validation. Receives the value and should return true if valid.
CORE METHODS
cli_run(\@ARGV, \%shortcuts)
MY->cli_run(\@ARGV) unless caller;
# With option shortcuts
MY->cli_run(\@ARGV, {h => 'help', v => 'verbose'}) unless caller;
Main entry point for CLI execution. Parses arguments, creates an instance, and invokes the appropriate method. Options before the command become constructor arguments, remaining arguments are passed to the method.
Option format: --name
or --name=value
(no space between name and value).
JSON values in options and arguments are automatically decoded:
$ ./MyScript.pm --config='{"port":8080}' process '[1,2,3]'
Command Methods
Official Commands (cmd_*)
Methods prefixed with cmd_
are official CLI commands:
sub cmd_import : Doc("Import data from file") {
my ($self, $file) = @_;
# Handle own output
print "Importing $file...\n";
# Handle own exit code if needed
exit($success ? 0 : 1);
}
Regular Methods
Regular methods have their return values automatically serialized:
sub calculate {
my ($self, $x, $y) = @_;
return {result => $x + $y}; # Will be JSON-encoded
}
Output Control Methods
cli_output(\@results)
Called automatically to output method results. Can be overridden for custom output handling.
cli_write_fh($filehandle, @data)
Low-level output method that respects the --output
format option.
OPTIONS
These options control CLI behavior and are processed by cli_run
:
--help
-
Show help message and exit
--quiet
-
Suppress normal output
--scalar
-
Evaluate methods in scalar context (default is list context)
--output=FORMAT
-
Output format:
ndjson
(default),json
,yaml
,tsv
,dump
,raw
--flatten
-
Flatten array results (useful with
--output=tsv
) --undef-as=STRING
-
How to represent undef in TSV output (default: "null")
--no-exit-code
-
Don't set exit code based on results
--binary
-
Keep STDIN/STDOUT/STDERR in binary mode (no UTF-8 encoding)
OUTPUT FORMATS
ndjson (default)
Newline Delimited JSON - one JSON object per line. Ideal for:
Large result sets (human readable without pretty-printing)
Pipeline processing with grep, awk, etc.
Streaming output
json
Standard JSON format with pretty-printing
yaml
YAML format (requires YAML::Syck)
tsv
Tab-separated values, useful for spreadsheet import
dump
Perl Data::Dumper output for debugging
raw
No serialization, raw string output
UTILITY METHODS
These methods are available for use in your modules:
cli_decode_json($json_string)
Decode a JSON string to Perl data structure
cli_encode_json($data)
Encode Perl data structure to JSON string
cli_read_file($filename)
Read and parse a file based on its extension (.json, .yml, .txt)
DEVELOPMENT WORKFLOW
CLI_JSON is designed to accelerate development through immediate feedback:
# 1. Create minimal module
package MyModule;
use MOP4Import::Base::CLI_JSON -as_base;
MY->cli_run(\@ARGV) unless caller;
1;
# 2. Check syntax
$ perl -wc MyModule.pm
# 3. Add a method and test immediately
$ ./MyModule.pm my_method "arg1" "arg2"
# 4. Debug interactively
$ perl -d ./MyModule.pm my_method "test"
# 5. Profile performance
$ perl -d:NYTProf ./MyModule.pm heavy_method
SEE ALSO
MOP4Import::Base::CLI - Base CLI class without JSON features
App::Cmd - Full-featured CLI framework for production applications
LICENSE
Copyright (C) Kobayasi, Hiroaki.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
AUTHOR
Kobayasi, Hiroaki <buribullet@gmail.com>