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