Dans les langages dynamiques orientés-objets tels que Ruby, Python ou Smalltalk, on dispose à la fois des concepts de classes et d'objets permettant la réalisation de mécanismes d'aiguillage dynamique, et de la notion de fermeture, ou lambda-abstraction, ou bloc, qui permet de modifier dynamiquement la définition de méthodes et de fonctions et leur utilisation comme valeurs de première classe.
Ces mécanismes combinés permettent d'obtenir un Visiteur plus simple, plus élégant et plus compact.
Le code du visiteur (ici, l'exemple de l'évaluateur) fait apparaître ces manipulations dynamiques. Chacune des méthodes visit_xxx fait référence à la méthode visit(self, node) qui utilise une table associative (dispatch) permettant de sélectionner une méthode à partir de l'identifiant du type récupéré dynamiquement (type(node)).
class ExpressionEvaluator(object): """Documentation for ExpressionEvaluator""" def __init__(self): super(ExpressionEvaluator, self).__init__() def visit_binary(self, node, op): return op(self.visit(node.left), self.visit(node.right)) def visit_and(self, node): return self.visit_binary(node, lambda x, y: x + y) def visit_sub(self, node): return self.visit_binary(node, lambda x, y: x - y) def visit_mul(self, node): return self.visit_binary(node, lambda x, y: x * y) def visit_div(self, node): return self.visit_binary(node, lambda x, y: x / y) def visit_literal(self, node): return node.value dispatch = { And: visit_and, Sub: visit_sub, Mul: visit_mul, Div: visit_div, Literal: visit_literal } def visit(self, node): return self.dispatch[type(node)](self, node)