Sunday 17 December 2017

Moo: One approach to terminating the process when attributes of a dynamically assigned role are missing

The value of a role’s required attribute is only checked on object creation. This article provides one way of enforcing it when applying the role to an object on the fly.

Picture of a Dalek

Introduction

What is certain about Perl programming is that there's always more to learn, and this article on applying roles in OO Perl is one such example. It's the challenge of ensuring attributes are set in roles applied on the fly.

It’s quite often the case that if people forget to assign a value to an attribute we really want things to die rather than have undef being returned as the value of the attribute.

Here's an example:
and when you run it:

In order to terminate the process so that the script behaves as follows:

all you need to do is make the "name" attribute "required":

This all works fine and dandy until you decide not to apply the role on creation of the object. In this example, it might be that a car can have a brand, or it might be home-made with no brand. At this point you have to remove the role declaration from the class and apply the role to the object:

As you can see from the following output - the "required" modifier isn't applied because that only happens on creation of the object.


"Terminate!" by default

Rather than requiring the attribute on object creation (before the role has been applied) the solution here is to make the attribute lazy, then die by default on accessing the attribute to indicate that a value hasn't been assigned.


Summary

A Moo role's "required" attribute isn't actually required if the role is being assigned to an object at runtime. One solution is to die by default when accessing the attribute with no assigned value.

Acknowledgements

This rabbit hole traversal was instigated by one of Dave Cross's rigorous code reviews.

No comments:

Post a Comment