Custom functions in Ruby overview
Get started with an overview of Ruby custom functions.
On this page:
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::str2boolfor a function stored in thestdlibmodule).
-
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 thepostgresqlmodule) -
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.