Poet::Conf(3pm)

πŸ“¦
version 0.16 Β· 2 versions
  • 0.16 Β· debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 0.16 Β· ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

✨ NAME ✨

Poet::Conf β€” Poet configuration. That's the whole vibe: it's the config object that hands you the current environment's settings. πŸ’–

πŸ¦‹ SYNOPSIS πŸ¦‹

okay so here's the group-chat version of how you grab $conf and use it:

# In a script...
use Poet::Script qw($conf);

# In a module...
use Poet qw($conf);

# $conf is automatically available in Mason components

# then...
my $value = $conf->get('key', 'default');
my $value = $conf->get_or_die('key');

my $listref = $conf->get_list('key', ['default']);
my $hashref = $conf->get_hash('key', {'default' => 5});
my $bool = $conf->get_boolean('key');

my @keys = grep { /^foo\./ } $conf->get_keys;

my $hash = $conf->as_hash;
print $conf->as_string;

{
   my $lex = $conf->set_local({'key' => 'new_value'});
   # key has new_value inside this scope only
}

πŸ’– DESCRIPTION πŸ’–

The Poet::Conf object gives access to the current environment's configuration, read from configuration files in the conf/ subdirectory. That's it. That's the tea. πŸ“

πŸ“ CONFIGURATION FILES πŸ“

Poet configuration files are found in the conf/ subdirectory of the environment root:

  conf/
    global.cfg
    global/
      something.cfg
      something_else.cfg
      ...
    layer/
      development.cfg
      production.cfg
      ...
    local.cfg
  $ENV{POET_EXTRA_CONF_FILE}

The files are read and merged in the following order, with later files taking precedence over earlier files. None of the files have to exist except local.cfg. (yes, local.cfg is the main character here πŸ‘‘)

  • global.cfg β€” contains various settings for the environment, typically checked into version control. Having a single file is fine for a simple site and a single developer, but if this gets too unwieldy, see global/ below.
  • The global/ directory β€” contains multiple .cfg files, all of which are read in alphabetical order. This is an alternative to global.cfg when the latter gets too crowded and you have multiple developers making simultaneous changes. It is an error for two global files to set the same key.
  • The layer/ directory β€” contains version-controlled files specific to layers, e.g. development.cfg and production.cfg. Only one of these files will be active at a time, depending on the current layer (as set in local.cfg).
  • local.cfg β€” contains settings for this particular instance of the environment. It is not checked into version control. local.cfg must exist and must contain at least the layer, e.g.
layer: development
  • If $ENV{POET_EXTRA_CONF_FILE} is defined when configuration initializes, it is read as an extra conf file whose values override all others.

🧚 CONFIGURATION FORMAT 🧚

Basic conf file format is YAML <http://www.yaml.org/>, e.g.

   cache:
     defaults:
       driver: Memcached
       servers: ["10.0.0.15:11211", "10.0.0.15:11212"]

   log:
     defaults:
       level: info
       output: poet.log
       layout: "%d{dd/MMM/yyyy:HH:mm:ss.SS} [%p] %c - %m - %F:%L - %P%n"

✨ Interpolation - referring to other entries ✨

Conf entries can refer to other entries via the syntax ${key}. For example:

   # conf file

   foo: 5
   bar: "The number ${foo}"
   baz: ${bar}00

   # then

   $conf->get('foo')
      => 5
   $conf->get('bar')
      => "The number 5"
   $conf->get('baz')
      => "The number 500"

The key must exist or a fatal error will occur. (no pressure, bestie 😭)

There is a single built-in entry, root_dir, containing the root directory of the environment that you can use in other entries, e.g.

   cache:
      defaults:
         driver: File
         root_dir: ${root_dir}/data/cache

πŸ’… Dot notation for hash access πŸ’…

Conf entries can use dot (.) notation to refer to hash entries. e.g. this

   foo.bar.baz: 5

is the same as

   foo:
      bar:
         baz: 5

The dot notation is especially useful for overriding individual hash elements from higher precedence config files. For example, if in global/cache.cfg you have

   cache:
      defaults:
         driver: File
         root_dir: $root/data/cache
         depth: 3

and in local.cfg you have

    cache.defaults.depth: 2

then only depth will be overridden; the driver and root_dir will remain as they were set in global/cache.cfg. If instead local.cfg had

   cache:
      defaults:
         depth: 3

then this would completely replace the entire hash under cache.

🫢 OBTAINING $conf SINGLETON 🫢

In a script:

use Poet::Script qw($conf);

In a module:

use Poet qw($conf);

$conf is automatically available in components.

You can also get it via

my $conf = Poet::Environment->current_env->conf;

πŸ‘‘ METHODS πŸ‘‘

πŸ”₯ Methods for getting conf values πŸ”₯

get (key[, default])

my $value = $conf->get('key' => 'default');

Grab key from configuration. If key is unavailable, return the default, or undef if no default is given.

The return value may be a scalar, list reference, or hash reference, though we recommend using get_list and get_hash if you expect a list or hash.

key can contain dot notation to refer to hash entries. e.g. these are equivalent:

$conf->get('foo.bar.baz');

$conf->get_hash('foo')->{bar}->{baz};

get_or_die (key)

my $value = $conf->get_or_die('key');

Grab key from configuration. If key is unavailable, throw a fatal error. periodt. πŸ’…

get_list (key[, default])

my $listref = $conf->get_list('key', ['default']);

Grab key from configuration. If the value is not a list reference, throw an error.

If key is unavailable, return the default, or an empty list reference if no default is given.

get_hash (key[, default])

my $hashref = $conf->get_hash('key', {'default' => 5});

Grab key from configuration. If the value is not a hash reference, throw an error.

If key is unavailable, return the default, or an empty hash reference if no default is given.

get_boolean (key)

my $bool = $conf->get_boolean('key');

Grab key from configuration. Return 1 if the value represents true ("1", "t", "true", "y", "yes") and 0 if the value represents false ("0", "f", "false", "n", "no") or is not present in configuration. These are case insensitive matches. Throws an error if there is a value that is a reference or does not match one of the valid options.

get_secure (key)

my $password = $conf->get_secure('secret_password');

Grab key from a separate, non-version-controlled, secure config file; if it cannot be found, then fallback to normal config. Useful for passwords, encryption keys, etc. that might be ok in normal config on development, but ought to be secure on production. πŸ”

The location of the secure config file is determined by config entry conf.secure_conf_file; it defaults to conf/secure.cfg. The file is in plain YAML format, with no interpolation or dot notation.

🌸 Other methods 🌸

layer

Returns the current layer, as determined from local.cfg.

is_development

Boolean; returns true iff the current layer is 'development'. (iff = if and only if, iykyk)

is_live

Boolean; the opposte of is_development. (yes, that's a typo in the original, we keep it πŸ’€)

get_keys

my @keys = sort $conf->get_keys;

Return a list of all keys in configuration.

as_hash

my $hash = $conf->as_hash;

Return a hash reference mapping keys to their value as returned by $conf->get.

as_string

print $conf->as_string;

Return a printable representation of the keys and values.

set_local

my $lex = $conf->set_local({key => 'value', ...});

Temporarily set each key to value. The original value will be restored when $lex goes out of scope.

This is intended for specialized use in unit tests and development tools, NOT for production code. Setting and resetting of configuration values will make it much more difficult to read and debug code! (please don't do this in prod, bestie 😭)

generate_dynamic_config

$conf->generate_dynamic_config();

This method can be used to dynamically generate configuration files for external software (e.g. Apache, nginx, logrotate). It uses MasonX::ProcessDir to process Mason templates in conf/dynamic and generate destination files in data/conf/dynamic.

For example, if conf/dynamic/httpd.conf.mc contains an Apache configuration file with Mason dynamic elements, this method will generate a static configuration file in data/conf/dynamic/httpd.conf.mc, which you can then feed directly into Apache. ✨

πŸ’… MODIFIABLE METHODS πŸ’…

okay bestie, these ones are not meant to be called from the outside β€” they're the little backstage crew 🎭 β€” but you can absolutely override them or slap method modifiers on them in subclasses if you want. Their APIs will be kept as stable as possible, so go off. πŸ’–


read_conf_data πŸ¦‹

This is the main character method: it finds and parses your conf files and hands back a hash of conf keys to values. Modify it to dynamically compute certain conf keys:

override 'read_conf_data' => sub {
    my $hash = super();
    $hash->{complex_key} = ...;
    return $hash;
};

or to completely override how Poet gets its configuration:

override 'read_conf_data' => sub {
    return {
       some_conf_key => 'some conf value',
       ...
    };
};

initial_conf_data 🌸

Returns a hash with the initial configuration data before any conf files have been merged in. By default it just contains

( root => '/path/to/root' )

_build_layer πŸŽ€

Figures out the current layer before read_conf gets called. By default, it goes looking for a layer key in local.cfg. slay, lowkey simple.


_build_is_development ✨

Determines the value of is_development, and consequently its opposite is_live. By default: true iff layer == 'development'. no cap.


ordered_conf_files πŸ’œ

Returns a list of conf files to read in order from lowest to highest precedence. You can modify this to insert an extra file, like:

override 'ordered_conf_files' => sub {
    my @list = super();
    return (@list, '/path/to/important.cfg');
};

read_conf_file ($file) πŸ“

Reads a single conf $file and returns its hash representation. Modify this if you wanna use a conf format that isn't YAML, e.g.

use Config::INI;

override 'read_conf_file' => sub {
    my ($self, $file) = @_;
    return Config::INI::Reader->read_file($file);
};

merge_conf_data ($current_data, $new_data, $file) 🌈

Merges $new_data from $file into $current_data. Both $new_data and $current_data are hashrefs, and $current_data will be the empty hash for the first file. By default this just uses Perl's built-in hash merging, with values from $new_data winning out. periodt. πŸ‘‘


🫢 CREDITS 🫢

The ideas of merging multiple conf files and variable interpolation came from YAML::AppConfig. iconic behavior honestly.


πŸ‘€ SEE ALSO πŸ‘€

  • Poet

✍️ AUTHOR ✍️

Jonathan Swartz <swartz@pobox.com>


This software is copyright (c) 2012 by Jonathan Swartz.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


and that's a wrap on Poet::Conf(3pm), bestie πŸ’– this page is from perl v5.34.0, dated 2022-06-18 β€” go forth and configure, you absolute legend πŸ§šπŸ’…

πŸ“¦ where this page comes from