Subsections

   
3 Receiver Patterns

Erlang provides pattern matching in its very syntax, which the receive statement uses to its advantage. Since Python does not provide pattern matching in its syntax, we must use a slightly different mechanism to match messages. The first argument passed to the Receiver.addHandler() method can be any Python value. The addHandler() method uses this value as a pattern and interprets it in the following way:

  1. If the value is the constant, candygram.Any, then any message will match.
  2. If the value is a type object or a class, then any message that isinstance() of the type or class will match.
  3. If the value is callable(), then a message will match if the function/method returns True when called with the message.
  4. If the value is a tuple, then a message will match only if it is a tuple of the same length. Also, each value in the tuple is used as a pattern and the tuple as a whole will match only if every sub-pattern in the tuple matches its associated value in the message.
  5. If the value is a list, then the same rule for tuples applies, except for the last sub-pattern. The last sub-pattern in the list can match zero or more values in the message. That is, the length of the message may be >= len(pattern)-1 as long as all excess values match the last sub-pattern.
  6. If the value is a dictionary, then a message will match only if it is a dictionary that contains all of the same keys as the pattern value. Also, each value in the dictionary is used as a pattern and the dictionary as a whole will match only if every pattern in the dictionary matches its associated value in the message.
  7. Lastly, addHandler() treats any other value as a literal pattern. That is, a message will match if it is equal to the given value.

3.1 Examples

Let's illustrate these rules by example.1 In the table below, the first column contains a Python value that is used as a pattern. The second column contains Python values that match the pattern and the third column contains Python values that do not match the pattern.
Pattern  Matches  Non-Matches 
Any 'text', 13.7, (1, '', lambda: true)  
'land shark' 'land shark' 'dolphin', 42, []
13.7 13.7 'text', 13.6, {'A': 14}
int 13, 42, 0 'text', 13.7, []
str 'plumber', '' 42, 0.9, lambda: True
lambda x: x > 20 42, 100, 67.7 13, 0, -67.7
(str, int) ('shark', 42), ('dolphin', 0) ['shark', 42], ('dolphin', 42, 0)
(str, 20, lambda x: x < 0) ('shark', 20, -54.76), ('dolphin', 20, -1) ('shark', 21, -6), (20, 20, -1), ('', 20)
['A', str, str] ['A', 'B', 'C', 'D'], ['A', 'B'] ['C', 'B', 'A'], ['A']
[str, int] ['dolphin', 42, 0], ['shark'] [42, 0], ['dolphin', 42, 'shark']
[Any] ['dolphin', 42, 0.9], [] ('dolphin', 42, 0.9), 'shark'
{'S': int, 19: str} {'S': 3, 19: 'foo'}, {'S': -65, 19: 'bar', 'T': 'me'} {'S': 'Charlie', 19: 'foo'}, {'S': 3}



Footnotes

... example.1
Do not use all of these patterns at home. These are highly trained stunt patterns and are displayed here for demonstration purposes only. Specifically, you should rarely ever use more than one sub-pattern in a list pattern, nor should you ever use more than one type of key in a single dictionary.
SourceForge.net Logo