Skip to content

Instantly share code, notes, and snippets.

@binford2k
Last active December 3, 2019 22:44
Show Gist options
  • Save binford2k/9bb00717ee59858a4a22fa981d52f6af to your computer and use it in GitHub Desktop.
Save binford2k/9bb00717ee59858a4a22fa981d52f6af to your computer and use it in GitHub Desktop.

Typecasting or converting between data types

A strong data type system provides a lot of safety. It means that you cannot accidentally pass a String when a Number was expected, for example. This simplifies logic all throughout your code and means that you'll need to write a lot less boilerplate error checking and type validation code.

But it also introduces a few new challenges, namely in that you now have to pay attention to data types and convert between them intentionally. This page will show you the different ways you can do that.

Creating a new typed variable

In many cases, when there's an unambiguous translation between one data type and another, you can simply typecast into the type you need.

$temp   = Float("98.6")       # Cast into a float variable; 98.6
$count  = Integer("42")       # Cast into an integer variable; 42
$bool   = Boolean("false")    # Cast into a boolean false
$string = String(100)         # Cast into the string "100"

You can even cast other number formats, such as turning a hex number string into an integer:

$intval =  Integer("0xFF")    # Cast into an integer variable; 255

Invoking the data type directly is a shortcut for calling the .new() function. The documentation for new() describes all the conversion rules and options.

Special cases or shortcuts

Some data conversion is common enough that the Puppet language has shortcuts designed for them. Likewise, some conversions are so complex that there are special considerations when invoking them. Some of the more common are described below.

Automatic coercions

When you use strings in arithmetic, Puppet will assume that you did so intentionally and will coerce them to the proper types. For example:

$result = "2" + "2"         # Cast into an integer variable; 4
$multiple = 4 * "25"        # Cast into an integer variable; 100
$float    = "2.75" * 2      # Cast into a float variable; 5.5
$identity = "1024" + 0      # Cast into integer variable; 1024 (direct conversion)

When you interpolate variables into a string, Puppet will convert them to their string representation using the most obvious method. If you need to convert otherwise, then you can manually typecast.

$var = 1
notice("The truth value of ${var} is ${Boolean($var)}") # Outputs "The truth value of 1 is true"

Extracting a Number from a String fragment

Sometimes the string you need to convert isn't clean, or just numeric characters. Strings like "32º" or "9,000" will not automatically coerce. Instead, you'll need to parse the string. The most common way to do that is by providing a format string to the scanf() function.

Example format conversions:

Conversion Description of match
%d, %u Optionally signed decimal integer
%i Optionally signed integer with autodetected base
%o Optionally signed octal integer
%x, %X Optionally signed hexadecimal integer
%s String, or a sequence of non-white-space characters
%c A single character
%% A literal % character

See the Ruby format string documentation for complete details.

To parse out a number with thousands separators, it's easiest to delete the separators first.

$input  = "It is 32º outside!"
$format = "It is %iº outside!"
scanf($input, $format)  # returns array of matches;  [32]

$input  = "The melting point of iron is 2,800°F".delete(",")
$format = "The melting point of iron is %i°F"
scanf($input, $format)  # returns array of matches;  [2800]

Converting to a Boolean

Old Puppet code often had relatively complex case statements to convert various values to boolean truth values. Today, you can simply typecast and Puppet will do it for you. You can cast case-insensitive strings of true/false, yes/no, non-zero/0, and integers of non-zero/0.

$value = Boolean('true')      # true
$value = Boolean('Yes')       # true
$value = Boolean('FALSE')     # false
$value = Boolean('1')         # true
$value = Boolean(0)           # false
$value = Boolean(127)         # true

Converting data structures

Converting a hash to an array will create a multi-dimensional array by flattening each key/value pair into a two-element array as an element of another array.

Converting an array to a hash will interleave alternating elements as keys and values.

$an_array = Array({a => 10, b => 20}) # results in [[a, 10],[b, 20]]
$a_hash   = Hash([1,2,3,4])           # results in {1=>2, 3=>4}
$a_hash   = Hash([[1,2],[3,4]])       # results in {1=>2, 3=>4}

The Array conversion also takes a second argument to "force" an array conversion. This slightly changes the semantics of the operation by creating a single-element array out of the first argument if it's not already.

$an_array = Array(1, true)        # results in [1]
$an_array = Array([1], true)      # results in [1]
$an_array = Array(1)              # Raises a type error, cannot convert directly
$an_array = Array({1 => 2}, true) # results in [{1 => 2}]
$an_array = Array({1 => 2}}       # results in [[1, 2]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment