jackthehipster
jackthehipster

Reputation: 1018

How does the Perl Template::Declare modul work in terms of Perl language syntax?

I need to create really complex XML documents (METS), using prefixes, namespaces, schema validation, document-internally referenced element IDs, attributes from mixed namespaces... pretty much everything XML allows you to do. Also there will be loads of heavily nested elements, making it difficult to track starting- and ending-tags manually.

Researching several possibilities to do that I came across Template::Declare.

The synopsis provides an example that I show here for reference:

template simple => sub {
        html {
            head {}
            body {
                p { 'Hello, world wide web!' }
            }
        }
    };

My question is: what is happening here in terms of Perl language elements? How does this translate to valid Perl syntax? For example, what are the "html", "head" keywords etc. here representing for the Perl compiler? Is that some implicit sub declaration? Perl does (or allows you to do) so many things implicitly that I never know what is actually happening. I don't want to just copy and paste some example and hope that I can bend it to do what I need, I'd actually like to know what I'm doing...

Can someone enlighten me here?

Upvotes: 1

Views: 46

Answers (1)

simbabque
simbabque

Reputation: 54373

The beauty of CPAN is that you can just take a look at the code. This one is a bit complicated I admit, but here is what you are looking for:

https://metacpan.org/source/ALEXMV/Template-Declare-0.46/lib/Template/Declare/Tags.pm#L525

Basically the sugary syntax comes from the prototype &, which tells Perl that the sub is accepting a code reference. The { ... } here are not hashes, they are blocks, the same as the ones in a map or grep. In your example, they are chained together.

Because of the prototype, you can ommit parenthesis and commas, but you could also write the example like this:

template simple => sub {
  html(
    sub {
      head(
        sub { },
        body(
          sub {
            p( sub { 'Hello, world wide web!' } );
          } ) );
    } );
};

The way this is implemented, if written out directly, would be:

sub template(%) { ... } # the % tells it to expect a hash
sub html(&) { ... }
sub head(&) { ... }
sub body(&) { ... }
sub p(&) { ... }

This kind of stuff is called Syntactic Sugar, or a DSL (Domain-Specific Language).

Note that you should only use prototypes in your code if you know what you are doing! Chances are, you do not want them.

Upvotes: 3

Related Questions