Auto-generating Dereferencing Code for Bermuda

Ovid on 2008-01-31T16:54:50

In auto-generating the code to serialize arbitrary objects, I might have an element definition which looks like this:

  - phone+
  - method: phone_numbers
    type: string

And that generates code which looks like this:

    my $count = 0;
    foreach my $phone ( $instance->phone_numbers ) {
        $count++;
        push @{ $self->{data}{elements} } => {
            name       => 'phone',
            attributes => {},
            value      => $phone,
        };
    }
    unless ($count) {
        croak("Method 'phone_numbers' failed to return at least one element");
    }

But what if phone_numbers returns an array reference? One thing I can do is make this explicit by prepending the attribute name with an '@' symbol.

  - @phone+
  - method: phone_numbers
    type: string

The '@' would only be valid if a '*' or '+' quantifier was on the element (or attribute) name. I've already done this and it makes the relevant bit of code look like this:

foreach my $phone ( @{ $instance->phone_numbers } ) {

However, I've been giving this some thought and I realized that if we have '*' or '+' quantifiers, the code should just know it needs to dereference an array reference, if found. This complicates things internally, but makes the user interface more DWIMery. However, DWIMery is a very Bad Thing if Do What I Mean doesn't match Do What You Need. I'll leave it explicit for right now, but I need to give this some thought.

Oh, and if you have no quantifier or a '?' quantifier, then the '$' prefix becomes valid to force scalar context (in case the method returns a list). Since there is no real way to automagically determine if this is what happens, a '$' prefix becomes mandatory.