## Durations vs Roles

So, I patched in some dodgy but working for this example code to handle the duration of notes. And then I started to think about how to do it properly.

About half of the musical elements in an ABC tune have a duration. So my first thought was, oooo, define an ABC::Duration role! I was excited, because this seemed like the first really good example I’d seen in my own work of where a role was appropriate and seemed superior to class inheritance.

So I started out defining a duration role with a Real attribute for its length, and two new methods, one which took a Real, and one which took the parsed bits of the note_length regex as strings. But then I started thinking about what that meant. If you define a class which does a role, how do you call that role’s new method? If I’m building up the AST, I’m going to want to create a duration before I have an element to attach it to — how do you build an element around an existing duration? And half of the objects which have durations are perhaps not best represented using a stored duration value — for instance, a triplet element’s duration is the total duration of its three wrapped notes, times 2/3 — making the stored duration value redundant.

So, this is one of those posts which I make before I’ve figured out what the answer is. I’ve verified that you can create a standalone role object in Rakudo:

> role Duration { has \$.duration; }; my \$a = Duration.new(:duration(10)); say :\$a.perl
"a" => .new(duration => 10)

So that’s one piece of the second point addressed. (Though surely that .perl is wrong?) But I’m not seeing how to do the rest of it at the moment.

Any ideas out there?

### 2 Responses to “Durations vs Roles”

1. Benabik Says:

According to S12…

role Duration {…}
my \$x = Duration.new

…is the same as…

role Duration {…}
class Duration does Duration {…}
my \$x = Duration.new

I quote from S12-objects.pod:

When the typename happens to be a role, autovivifying it involves
attempting to create a punned class of the same name as the role.
Whether this succeeds or not depends on whether the role is
sufficiently complete to serve as a class on its own.

2. mathw Says:

What you’re doing there is actually creating a new class on the fly which has the role composed into it (and contains nothing else), and then making a new object of that class immediately. I don’t think it’s the kind of thing you can then seamlessly merge into an instance of another class which composes the same role.

Which I suspect is why the .perl comes out wrong, although it should probably manage to be smarter than that.

But I think the correct pattern here might be having a Duration object which then becomes a member of the thing which has a duration. I did once come across a genuine use for roles, but I was coding in C++ so I had to use multiple inheritance instead. I know people are using them with Moose, but personally I have no idea of the patterns involved.