extending <% | %>

Hans Dieter Pearcey <[email protected]> Wed, 16 Jan 2008 11:12:04 -0500
Newsgroups gmane.comp.web.mason.devel
Message-ID <[email protected]>
Attached is a patch that makes | in substitutions more powerful.  This isn't
finished; it does work, and all but two of the existing tests pass with it, but
the implementation feels a bit fragile and there's no documentation.

There are two major changes.

The first is that there can be multiple |s in a substitution, and each can have
arguments (which can be arbitrary Perl).  I called these 'filters', even though
that's kind of an overloaded word now (so I'm open to suggestions).

The second is that instead of evaluating the LHS of a substitution immediately,
it's wrapped in sub { } and passed to the filters that way; this gives more
control to the filters, because evaluation is delayed.

Some examples will probably be clearer:

  <% $object->expensive_method(\%args) | cache(expires_in => "10m") | h %>

(there's a test that demonstrates that in t/10-cache.t)

  <% $biller->calculate_amount | format('$%5.2f') %>

The old escape_flags and apply_escapes are now implemented in terms of filters.
They keep working anywhere in the filter pipeline; the only special casing done
for them is that escape flags are parsed specially when they're the last filter
entry, so that this keeps working: 
  
  <% $foo | h, u %>

But this would also work:

  <% $foo | h | u | cache %>

I also did some refactoring of cache_self -- '| cache(...)' uses the same
arguments as cache_self, and I didn't want to reinvent the wheel.  See
HTML::Mason::Request::_cache_access (the name sucks).  We probably want
something like this independent of the rest of the patch; it makes writing
cache_self analogues much easier.

Because LHS evaluation is delayed, I had to do some ugly things to make sure
that globals referred to on the LHS were still around at $m->print time,
especially $_ and @_.

One thing I can't fix is that wantarray becomes useless in <% %> (it will
always be true).  It used to reflect the calling context of exec().

Look at HTML::Mason::Filters for how cache() and format() are written.  In
particular, the latter is written pretty much exactly how an 'escape' used to
be.

Things I have not yet done, but consider necessary or very useful for this
being 'finished':

 * cache() should autogenerate a unique cache key per <% %> (and maybe even
   per-filter, per-substitution), so that it's trivial to stick '| cache' onto
   existing substitutions

 * more real-world useful filters

 * documentation and tests, obviously

If all goes well, I would next move on to something like this:

<%| cache %>
A bunch of text here, including <% $more->stuff %>
with maybe some <& /component/calls &>
you know, lots of text, that would be annoying to put inside a
  <% $substitution %>
</%>

(but let's paint that bikeshed after we're done with this one)

hdp.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/