Custom functions in Ruby overview
Get started with an overview of Ruby custom functions.
Syntax of Ruby functions
To write a new function in Ruby, use the Puppet::Functions.create_function
method. You don’t need to
require
any Puppet
libraries. Puppet handle libraries automatically when it
loads the function.
Puppet::Functions.create_function(:<FUNCTION NAME>) do dispatch :<METHOD NAME> do param '<DATA TYPE>', :<ARGUMENT NAME (displayed in docs/errors)> ... end def <METHOD NAME>(<ARGUMENT NAME (for local use)>, ...) <IMPLEMENTATION> end end
The create_function
method requires:
- A function name.
- A block of code (which takes no arguments). This block contains:
- One or more signatures to configure the function’s arguments.
- An implementation method for each signature. The return value of the implementation method is the return value of the function.
For example:
# /etc/puppetlabs/code/environments/production/modules/mymodule/lib/puppet/functions/mymodule/upcase.rb Puppet::Functions.create_function(:'mymodule::upcase') do dispatch :up do param 'String', :some_string end def up(some_string) some_string.upcase end end
Location
Place a Ruby function in its own file, in the lib/puppet/functions
directory of either a module or an
environment. The filename must match the name of the function, and have the .rb
extension. For namespaced functions, each segment prior to the
final one must be a subdirectory of functions
, and the final
segment must be the filename.
Function name | File location |
---|---|
upcase
|
<MODULES
DIR>/mymodule/lib/puppet/functions/upcase.rb
|
upcase
|
/etc/puppetlabs/code/environments/production/lib/puppet/functions/upcase.rb
|
mymodule::upcase
|
<MODULES
DIR>/mymodule/lib/puppet/functions/mymodule/upcase.rb
|
environment::upcase
|
/etc/puppetlabs/code/environments/production/lib/puppet/functions/environment/upcase.rb
|
metadata.json
file, it loads custom functions only from
those specific dependencies.
Names
Function names are similar to class names. They consist of one or more segments. Each segment must start with a lowercase letter, and can include:
-
Lowercase letters
-
Numbers
-
Underscores
If a name has multiple segments, separate them with a double-colon (::
) namespace separator.
Match each segment with this regular expression:
\A[a-z][a-z0-9_]*\Z
Match the full name with this regular expression:
\A([a-z][a-z0-9_]*)(::[a-z][a-z0-9_]*)*\Z
Function names can be either global or namespaced:
-
Global names have only one segment (
str2bool
), and can be used in any module or environment. Global names are shorter, but they’re not guaranteed to be unique — if you use a function name that is already in use by another module, Puppet might load the wrong module when you call it. -
Namespaced names have multiple segments (
stdlib::str2bool
), and are guaranteed to be unique. The first segment is dictated by the function’s location:-
In an environment, use
environment
(environment::str2bool
). -
In a module, use the module’s name (
stdlib::str2bool
for a function stored in thestdlib
module).
-
Most functions have two name segments, although it’s legal to use more.
Examples of legal function names:
-
num2bool
(a function that could come from anywhere) -
postgresql::acls_to_resource_hash
(a function in thepostgresql
module) -
environment::hash_from_api_call
(a function in an environment)
Examples of illegal function names:
-
6_pack
(must start with a letter) -
_hash_from_api_call
(must start with a letter) -
Find-Resource
(can only contain lowercase letters, numbers, and underscores)
Passing names to create_function
as symbols
When you call the Puppet::Functions.create_function
method,
pass the function’s name to it as a Ruby symbol.
To turn a function name into a symbol:
-
If the name is global, prefix it with a colon (
:str2bool
). -
If it’s namespaced: put the name in quotation marks, and prefix the full quoted string with a colon (
:'stdlib::str2bool'
).
Related topics: Puppet modules, Environments, Main manifest, Module metadata, Ruby symbols.