On Wed, Mar 02, 2005 at 12:42:08PM -0600, Rod Adams wrote:
: Larry Wall wrote:
: 
: >On Tue, Mar 01, 2005 at 11:06:17PM -0600, Rod Adams wrote:
: >: Since the line between rules and subs is already blurring significantly, 
: >: I want to blur it a little more. I want to write rules which can take 
: >: parameters.
: >
: >No problem.  That's how the arguments to rules like <before foo> are
: >already passed. 
: >
: Excellent!
: 
: >Of course, one can call them like ordinary methods too, as long as one
: >supplies an appropriate pattern-matching context invocant.  But it's
: >pretty handy to have that magically supplied for you inside <...>.
: > 
: >
: 
: Now for the tricky part.
: 
:   rule baltag (Str $tag, Str $body is rw) {
:     \< $tag .*? \>
:     $<body> := (.*?)
:     \</ $tag \>
:   }

Well, that would be written:

  rule baltag (Str $tag, Str $body is rw) {
    \< $tag .*? \>
    $body := (.*?)
    \</ $tag \>
  }

since $body is a real variable rather than a hash entry.  However,
I don't think binding works even in an ordinary sub--rebinding the
variable would break its association with whatever actual parameter.
You'd need to use assignment:

  rule baltag (Str $tag, Str $body is rw) {
    \< $tag .*? \>
    (.*?)
    \</ $tag \>
    { let $body = $1 }
  }

:   $buffer ~~ / <baltag title $<body>> .* \> <$body> \< /;

That'd have to be something like:

  $buffer ~~ / <baltag(/title/,$<body>)> .* \> <$body> \< /;

But in theory it should autovivify the $<body> for you based on the "is rw".

: In other words, I want to pass a possibly unbound hypothetical into a 
: subrule, and let the subrule bind/rebind it.

Can only assign it.  You'd have to pass the actual symbol table holding
$<body> if you want to rebind the name.  You could presumably pass
in $/ as an argument and hash it explicitly.

: Alternatively would be a syntax for calling the subrule, and then 
: binding a hypothetical to one of the hypotheticals returned in the 
: subrule. I'm moderately sure S05 made this possible, but I couldn't put 
: all the pieces together. I'll hazard the following guess:
: 
:   rule baltag (Str $tag) {
:     \< $tag .*? \>
:     $<body> := (.*?)
:     \</ $tag \>
:   }
: 
:   $buffer ~~ / $<btag> := <baltag title> <($<body> := $btag<body>)> /;

That's essentially correct, though that should probably be {...}
instead of <(...)>, in case the body has the value "0" which would
cause the <(...)> assertion to fail.  There might also be some
circumstances in which you need a "let" in there if there's any
possibility of backtracking over the binding but still having access
to the match object.

: Which seems very clumsy, especially if I wish to call it a lot. Be nicer 
: if I could push the work onto the subrule.

Well, if you never want <baltag> to return the tags, then you can just
say something like:

  rule baltag (Str $tag) {
    \< $tag .*? \>
    $0 := (.*?)
    \</ $tag \>
  }

  $buffer ~~ / $<body> := <baltag title> /;

But you probably want to know what attributes that first .*? matched too.

Larry

Reply via email to