Morpheus - the ultimate configuration engine


version 0.46


  use Morpheus "/foo/bar" => [
      qw($V1 $V2 $V3),
      "v5" => '$V5', "v6/a" => '$A',
      "v7" => [ '$C', '$D', "e" => '$E' ],

  use Morpheus -defaults => {
      "/foo/bar" => { x => 1, y => 2},

  use Morpheus -overrides => {
      "/foo/bar" => { "x/y" => 3 },

  use Morpheus -export => [
      qw( morph merge normalize )

  use Morpheus; # only 'morph' function is exported by default

  $bar = morph("/foo/bar");


Morpheus is a configuration engine that completely separates config consumers from config providers.

Consumers can obtain configuration values by using this module or morph script. Configuration values are binded to various nodes in the global config tree, similar to virtual file system. Consumers can ask for any node or for any subtree.

Providers are plugins which can populate configuration tree from any sources: local configuration files, configuration database, environment, etc. The overall program configuration is merged together from all data provided by plugins.


Every config value is binded to a key inside the global configuration tree. Keys use / as a separator of their parts, similar to usual filesystem conventions.

Any value which is a hashref will become the subtree in the configuration tree and will be merged with other values if possible. For example, if one plugin provides { foo => 5 } for /blah key, and another plugin provides { bar => 6 } for /blah key, then morph("/blah") will return { foo => 5, bar => 6 }.

Leading / in key name is optional, and morph("/foo") and morph("foo") are the same by now, but in the future some analog of chdir may be implemented. So leading / is probably more compatible with future releases.


There are a lot of things which you can pass to use Morpheus:

Import to global variables

This code will set your package's $X variable to the value binded to /foo/bar/X key:

  use Morpheus "/foo/bar" => [

You can pass several variables in the list:

  use Morpheus "/foo/bar" => [
    qw( $X $Y $Z )

Import value to variable with the name different from key's last part:

  use Morpheus "/foo/bar" => [
    "X" => '$FOO_BAR_X',

Or go to the next level in configuration tree:

  use Morpheus "/foo" => [
    blah => '$FOO_BLAH',
    bar => [ "X" => '$FOO_BAR_X' ],

Set defaults and override already defined values

This code will set default values for /foo/bar/x and /foo/bar/y:

  use Morpheus -defaults => {
    "/foo/bar" => { x => 1, y => 2 },

Since hashrefs and tree nodes are always equivalent in Morpheus, these following versions of code do the same thing too:

  use Morpheus -defaults => {
    "/foo" => { bar => { x => 1, y => 2 } },


  use Morpheus -defaults => {
    "/foo/bar/x" => 1,
    "/foo/bar/y" => 2,

Values which are set in this fashion are only defaults and will be overriden if any other plugins provide them too.

If you'll say -overrides instead of -defaults, on the contrary, your values will override any values provided by plugins.

Import helper functions

This module provides several helper functions. They can be imported into your code like this:

  use Morpheus -export => [
      qw( morph merge normalize )

If this -export option is not specified, then only morph() function will be imported.

More about these functions below


These functions can be imported via -export option.


Get value by given key. This function is imported by default.


Expand data by replacing all keys containing / in their names with nested hashrefs.

For example, normalize({ "a/b/c" => "d" }) will return { a => { b => { c => "d" } } }.

merge($value, $patch)

Merge two configuration subtrees together, including all deeply nested substructures.


Andrei Mishchenko <>


This software is copyright (c) 2012 by Yandex LLC.

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