John Hardin wrote:

An awful lot I think could be done simply by having rules that can capture to named per-message-global variables, and allowing those variables to be used in other (or the same) rules.

I've been wanting this for years.

Proposal for discussion:

Consider the following rules that could be in a user_prefs on a system that allows per-user rules:

   header __TO_ME   To:Addr    /<me\@myhost\.com>/
   meta    NOT_TO_ME    !__TO_ME

This could be useful for a single user, but obviously could not be site-wide, even if the site found such a thing useful, as all users have their own email addresses. The problem is obviously the hard-coded address string.

PMS has a number of per-message variables attached to it that can be used in the Perl code for various things. I'm proposing a way to add per-message constants and variables to this collection, and a way to access them in rule text.

Consider this variation on the above rules:

   variable __ME            /me\@myhost\.com/
   header    __TO_ME    To:Addr    /<$(__ME)>/
   meta    NOT_TO_ME    !__TO_ME

The format of the "variable" declaration is deliberately the simplified form of a rule declaration to simplify parsing and help file description considerations. Since it is actually defining a constant it could be called "constant". I called it "variable" because the thing it defines could vary from user to user and message to message.

Now we can put the __ME in each user_prefs and have a global rule in some site-global rules file. Each __ME instance would stick the string into a PMS variable for the duration of the message being parsed. The name of the PMS variable would be some variation on the "rule" name of the variable.

The text of the rules with a $(name) string in them, to be compiled, would have to have a way to reach into the relevent PMS variable to resolve that part of the string. Perhaps this means that rules containing variables could not be compiled. As the number of them is likely to be relatively small compared to the number of all rules, that is probably an acceptable tradeoff.

There are no execution ordering problems as long as 'variable' declarations are parsed before rules are run.

Now consider variable capture from the message:

header __SUB_CAP Subject:Capture /Your (\w+) Order/i $(__COMPANY)=\1

Here we can define a PMS variable and populate it on a rule match. The rule can be used as any normal rule, it just additionally captures one or more variables while it runs.

We can use this is a match against some other message part with a rule similar to the __TO_ME rule above. Obviously in this case we have rule ordering to consider, since we have to capture (or attempt the capture; the string may come up null) before we can run the rule depending on the string.

An alternative to the above capture symtax could be:

   header __COMPANY    Subject    /Your (\w+) Order/

The disadvantages I see to this are that you can only capture one string from the match, and you now have to wonder whether a rule name represents and integer or a string or both. I'm not in favor of the mess this could create.

Note that you could extend this fairly trivially (in a syntactic sense) to allow a match against multiple captured strings in a pattern:

   variable    __GROUP    /Order for $(__ME_) from $(__ORDER)/
   body        MY_ORDER    /$(__GROUP)/i    # __GROUP exists in the body

This also gets into problems of rule dependencies, since now some 'variable' declarations could not be executed until other rules have run. But it might be worth considering as an extension. Likely the mechanisms to implement the constant declaration, capture, and match code would be most all that was necessary to implement this too.

I think that the above would do most of what people would like to do.

Errors:

A reference to an undefined variable would be a rule syntax error, invalidating that rule.
   A poorly formatted capture would be a rule syntax error
   A poorly formatted variable would essentially be a rule syntax error.
Circular references would be a rule syntax error, invalidating the rule where it was detected (which could then invalidate other depending rules)

A dependency on text from a net rule would push other depending rule evaluation to after the net rules returned results. I assume this is already done for meta rules that depend on net rules. But I could see this potentially being a pain point.

I'm not married to any of the above suggested syntax; it just seemed like a reasonable starting point, and simple to describe and to use. Discussion and suggestions on the formats are welcome.

I don't know what it would mean to put a 'variable' name in a meta. Likely it would be meaningless and probably disallowed. Likewise I don't see much point in assigning a score or a description to a varable, since they aren't really rules themselves.

Discussion is open!

       Loren

Reply via email to