NAME
App::Ground - Ground your application.
DESCRIPTION
In circuit design, "ground" (GND) is a shared reference node (often called "0V") and a current return path. It is convenient because you can connect to it from many places, but it is not magic: real circuits may have multiple grounds, local grounds, and bad grounding can create noise or loops.
App::Ground uses the same metaphor for programming: it provides a small set of modules that act like a "ground" for infrastructure dependencies (logging, configuration, application handle, optional request context). This reduces parameter plumbing, but it should be used for infrastructure, not business data.
This is the classic trade-off of ambient authority vs dependency injection: globals are convenient, DI is explicit.
EXAMPLES IN OTHER LANGUAGES
JavaScript / Node.js
console.log('hello'); // global logging sink
const port = process.env.PORT; // global-ish configuration
Rust
log::info!("hello"); // global logger backend set once at startup
Go
// context.Context: one value passed through the stack, used by deep code.
Node.js (AsyncLocalStorage)
// per-async-chain "ambient" context (request id, trace ids, and so on).
Java
private static final Logger LOG = LoggerFactory.getLogger(X.class);
// Per-request context is often stored in ThreadLocal / MDC.
USAGE (THIS DISTRO)
This distribution ships several tiny "ground" modules.
C - Context
use C;
C::app($app);
my $db = C::db;
my $cfg = C::config;
Optional request context (for example a Mojolicious controller) can be stored in the package variable $C::C and read via C::C():
sub handler {
my ($c) = @_;
local $C::C = $c;
deep_call();
$c->render(text => 'ok');
}
sub deep_call {
my $c = C::C() or return;
# ...
}
Note: dynamic scoping (local) does not automatically cross async or promise boundaries. If you defer work, capture the context and re-localize it in the callback.
L - Logging
use L;
L::info "Hello\\n";
To replace the logger implementation (for example with Mojo::Log):
$L::logger = sub { $app->log };
You can also override it temporarily:
local $L::logger = sub { My::Test::Logger->new };
U - Utilities
U utilities use C for configuration and L for logging. For example, U::ewarn reads C::config->{Debug}{to} and sends emails via Email::Stuffer.
AUTHOR
Eugen Konkov