Exercice de méta-programmation
Cet exercice est inspiré de http://www.devsource.com/c/a/Languages/An-Exercise-in-Metaprogramming-with-Ruby/ qui semble mort :(
Cet exercice est réalisable dans les langages à objets qui possèdent un méta-niveau. Dans la suite on utilise Ruby et Java comme langages cibles, mais Python et C# fonctionneraient aussi.
Savoir lire la doc est important, partez de ces classes pour trouver l’information utile.
- Ruby: https://ruby-doc.org/core/Module.html et https://ruby-doc.org/core/Class.html
- Java: https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html
Création d’instances par meta-programmation
Implémentez la méthode strinit
qui prend une classe et une String et qui instancie cette classe avec les valeurs de la String qui sont séparées par des virgules.
Code initial en Ruby: meta1.rb
En Java: Meta1.java et Personne.java
Créations d’objets lus d’un fichier CSV
Implémentez la méthode csvinits
qui prend un nom de fichier CSV et pour chaque ligne instancie un objet du fichier (en utilisant strinit
).
- La première ligne du fichier est ignorée (on l’utilisera plus tard).
- Le nom de la classe à instancier est déduite du nom du fichier.
Le fichier personne.csv:
prenom,nom
Jon,Snow
Daenerys,Targaryen
En Ruby: meta2.rb
En Java: Meta2.java
Création de classe lue d’un fichier CSV
Ceci n’est pas réalisable directement en Java, mais est faisable en Ruby et Python.
Créez une méthode csvclass
qui prend un nom de fichier CSV et retourne les instances d’une classe anonyme ainsi que la classe anonyme elle-même (retour multiple).
- Important: vous devez créer une classe à partir de rien
La classe anonyme a les caractéristiques suivantes:
- Il y a un accesseur en lecture (getter) pour chacun des champs du CSV. Le nom des champs est donné dans la première ligne du fichier.
- Il y a un constructeur qui prend les arguments et les initialise dans l’ordre.
En Ruby: meta3.rb
Typage des champs
Ceci n’est pas réalisable directement en Ruby ou Python (pas de types statiques), mais est faisable en Java et C#.
Dans les exemples précédents, les champs de nos objets étaient tous de type String. Maintenant il faut convertir les champs dans les bons types.
Ce qui change:
- la classe doit avoir un constructeur public sans paramètre.
- pour chacun des champs
foo
du CSV il doit y avoir un settersetFoo
dans la classe. - le type du paramètre du setter détermine le comportement à adopter pour les champs:
- si le type est String, le champ de l’objet doit être initialisé directement du CSV.
- si le type est un type primitif, la valeur du champ doit être parsée (par exemple avec
Integer.parseInt
) - si le type est une autre classe, cette autre classe doit avoir un constructeur qui accepte un unique paramètre de type String.
Des données de bataille.csv:
nom,annee,decisive
Massacre à Durlieu,302 AC, true
Bataille de Chateau Noir, 301 AC, true
Bataille de Qohor, 100 BC, true
Bataille de Ironrath, 301 AC, false
En Java: Meta4.java, Bataille.java, Annee.java