Perl best practices part 2: getting Properties

Written by: Electric Bee
4 min read

Last week, we explored how to use ElectricCommander properties to ease and speed up your step development. This week, we will build on last week function InvokeCommander() .

sub getP()

Accessing a property value in ElectricCommander is easy and straightforward. You have several options:

  • Standard substitution: $. The problem is if the property does not exit, the step fail even before it start.

  • You can use the special Javascript property $ but I found the syntax a little confusing.

  • And finally you can use the API $ec->getProperty(“/path/to/my/property”) but again the step will fail if the property does not exist, this time at run time.

But now we have this awesome function InvokeCommander() on which we can build to get our property and manage error cases gracefully. So with one of my colleagues, Mike Westerhof, we came up with getP() which is basically $ec->getProperty(), returning either the property value or undef in case of error. As you can see in the code below, it’s a simple encapsulation with InvokeCommander() and some basic error management.

####################################################################### # # Return property value or undef in case of error (non existing) # ####################################################################### sub getP { my $prop=shift;

my($success, $xPath, $errMsg, $errCode)= InvokeCommander("SuppressLog IgnoreError", "getProperty", $prop); return undef if ($success != 1); my $val= $xPath->findvalue("//value"); return($val); }

To use it simply invoke:

$value=getP(“/path/to/my/property”);

sub getPS()

Of course, once you have single property covered, you need to start thinking about a bunch of them, either as a set of properties on an object or as a simple PropertySheet. Fortunately, we can group some two cases in one call using the path option for getProperties(). The other question is of course about depth. Do you want to get only the top level properties or work you way down in nested PropertySheets? So again with Mike’s help, we wrote getPS(). Our main discussion was around what data structure to use and we finally decided on using Hash references. We agreed it’s not necessarily the easiest structure but it’s efficient and fairly explicit. If you’re going to learn Perl, you’ll definitively need this tool in your arsenal anyway. So here is an example on how to use getPS() to get the properties associated with an artifact version. I wrote it for a customer (a large toy manufacturer) who asked for it on the day I coded getPS. Talk about great timing!

# # The second argument is a Boolean to recurse or not # getPS() returns a Hash reference # my $propertyHashRef = getPS("/artifactVersions/$group:$key:$version", 0);

# # Loop on the Hash keys # foreach my $name (keys($propertyHashRef)) { print "Property: $namen"; print "Value " . $propertyHashRef->{"$name"} . "n"; }

Here is another example with recursivity this time. When a nested PropertySheet is found in getPS(), a new Hash is created and the reference is associated with its name (the key) instead of a “normal” value. So when we explore the returned Hash reference, we need to test if the entry is a Hash or a “normal” entry. For greater visibility, the indentation is increased at each sub-level when printing the results (if you’re not a Perl specialist, the ‘x’ operator is the replicator -in our case, we “multiply” two spaces by the depth level to create indentation)

$ $

my $propertyHashRef = getPS("/server/ec_ui", 1); displayNestedPS($propertyHashRef, 0);

sub displayNestedPS() { my $Href=shift; # Hash reference my $depth=shift; # Depth level (for indentation)

foreach my $name (keys($Href)) { printf("sProperty: sn", " " x $depth, $name); # testing for a nested PS if (ref($Href->{"$name"}) eq 'HASH') { displayNestedPS($Href->{"$name"}, $depth+1); } else { # normal property printf("sValue: s n", " " x $depth, $Href->{"$name"}); } } }

Conclusion

We looked at how to build on top of InvokeCommander() with two very common needs. Those 2 functions are part of the EC-Admin project (version 1.3.3) and can be found on our GitHub Commander repository at https://github.com/electriccommunity/electriccommander/tree/controller/EC-Admin . My goal is to grow this library of functions to make it more useful for our customers so if you have any ideas or needs, contact us directly by email .

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.