durusmail: qp: ConnectiveSpecOperator: how to know which spec gave out?
ConnectiveSpecOperator: how to know which spec gave out?
2006-02-26
2006-02-27
2006-02-27
2006-02-27
2006-02-27
2006-02-27
2006-02-28
2006-02-28
ConnectiveSpecOperator: how to know which spec gave out?
mario ruggier
2006-02-26
I would like to be able to know which of the specs of a
ConnectiveSpecOperator caused the match to fail (or to succeed in the
case of either). This will enable me to be able to for example select a
more appropriate error message.

Toying with the code, I feel the following reorganization of the
current ConnectiveSpecOperator classes is quite reasonable, and does
not break anything.

The idea is that the main loop over each spec (inside __call__) calls a
matchone method, whose responsibility is to return True or False if it
knows that the ConnectiveSpecOperator has succeeded or failed, or
return None if it cannot determine yet. In the case of "pre-emptive"
succeed or fail, the spec that is the source of that is remembered in
an attribute such as CSO.break_spec, that client code (knowing that it
is dealing with a CSO) can query for...

Same effect may be achieved, maybe more simply, by doing something like
a "raise MatchNow()" on success and a "raise NotMatchNow()" on failure,
instead of returning anything from matchone().

How would you feel about such a change?


class ConnectiveSpecOperator (SpecOperator):

     def __init__(self, *specs):
         self.specs = specs
         self.args = self.specs
         self.break_spec = None

     def __call__(self, value):
         self.break_spec = None
         for spec in self.specs:
             matchedone = self.matchone(value, spec)
             if matchedone is not None:
                 self.break_spec = spec
                 return matchedone
         return True

class no (ConnectiveSpecOperator):

     def matchone(self, value, spec):
         if match(value, spec):
             return False
         return None

class both (ConnectiveSpecOperator):

     def matchone(self, value, spec):
         if not match(value, spec):
             return False
         return None

class either (ConnectiveSpecOperator):

     def matchone(self, value, spec):
         if match(value, spec):
             return True
         return None

reply