Lua: Le tutoriel  wxWidgets
Lua
Les coroutines: Les coroutines et les itérateurs.

Vous pouvez voir les itérateurs comme un exemple très concret du modèle producteur --> consommateur.

Un itérateur produit des articles qui seront ensuite consommés par le corps de la boucle.
Il semble donc approprié d'utiliser les coroutines pour écrire les itérateurs.

En fait, les coroutines fournissent un outil puissant pour cette tâche.
Car encore une fois, la principale caractéristique des coroutines est la capacité à tourner à l'envers, la relation entre l'appelant et l'appelé.
Avec cette fonctionnalité, vous pouvez donc écrire un itérateur sans vous soucier de conserver l'état entre les appels successifs à l'itérateur.

Pour illustrer ce type d'utilisation, vous allez écrire un itérateur afin de parcourir toutes les permutations d'un tableau donné.

Ce n'est pas une tâche facile et il est plus simple d'écrire une fonction récursive qui génère toutes les permutations.

L'idée est simple: Mettez chaque élément du tableau en dernière position et générez de façon récursive toutes les permutations possibles des éléments restants.
Ceci étant, le code pourrait ressembler à ce qui suit:

		function permgen(a, n)
		  if n == 0 then
			 printResult(a)
		  else
			 for i = 1,n do    
			 -- on met le ième élément à la dernière place.
				a[n], a[i] = a[i], a[n]    
			 -- on génère les permutations des autres éléments.
				permgen(a, n - 1)    
			 -- on restaure le ième élément.
				a[n], a[i] = a[i], a[n]    
			 end
		  end
		end
				

Il faut maintenant définir une fonction printResult appropriée et appeler permgen avec les arguments adéquats.

		function printResult(a)
		  for i,v in ipairs(a) do
			 io.write(v, " ")
		  end
		  io.write("\n")
		end
			 
		permgen ({1,2,3,4}, 4)
				

Changez maintenant printResult par une coroutine.yield.

		function permgen(a, n)			
		  if n == 0 then
			 coroutine.yield(a)
		  else
		  ...

Maintenant définissez une fonction qui fasse que le générateur tourne dans une coroutine, puis crée la fonction d'itération.
L'itérateur reprendra simplement la coroutine pour produire la permutation suivante.

		function Perm (a)
		  local n = table.getn(a)
		  local co = coroutine.create(function()
			 permgen(a, n) end)
		  return function()   -- iterator
			 local code, res = coroutine.resume(co)
			 return res
		  end
		end
				

La fonction Perm utilise un modèle commun en Lua, qui enveloppe un appel permettant de reprendre ses coroutines correspondantes à l'intérieur d'une fonction.

Ce modèle est si courant que Lua fournit une fonction spéciale: coroutine.wrap().

Comme create , wrap crée une nouvelle coroutine.

Contrairement à create , wrap ne retourne pas la coroutine mais, une fonction qui, lorsqu'elle est appelée, reprend la coroutine.

Contrairement à resume , cette fonction ne retourne pas de code d'erreur, mais soulève l'erreur au cas ou.

		function Perm(a)
		  local n = table.getn(a)
		  return coroutine.wrap(function() permgen(a, n) end)
		end
				

Habituellement, coroutine.wrap() est plus simple à utiliser que coroutine.create() car elle donne exactement ce dont vous avez besoin: une fonction de reprise.

Mais elle est aussi moins souple, car il n'existe aucun moyen de vérifier son statut et les erreurs éventuelles.

logo wxWidgets Le savoir ne vaut que s'il est partagé par tous...
logo-internet_32x32.png Dernière mise à jour, le 17 décembre 2012.
Valid XHTML 1.0 Transitional

wxlualogo
Flèche haut
Flèche gauche
Flèche haut
Flèche droite