Je viens de me lancer dans un nouveau blog (oui, je sais, vu l'activité de ce celui-ci...) à propos de jeu(x), toutes catégories confondus : jeux de plateaux, jeux de rôle, jeux vidéos (de préférence libres ou indés si possible...) et autres.
C'est l'occasion de faire mes petites fiches de jeu, de me remettre un peu à publier sur un sujet qui me plait, et accessoirement de tester Tumblr qui me parait être une plate-forme bien pratique...
lundi 22 mars 2010
Tumblelog de jeu
Publié par Sobe à 21:06 1 commentaires
jeudi 15 mai 2008
Ruby : Création dynamique de méthodes
Pour cela, il envisage trois voies : le def classique, la méthode define_method ou l'une de ces deux dans un eval. Plusieurs paramètres importants dans le choix de la méthode utilisée :
- Performances (à ce titre, voir cet article déconseillant l'usage de la métaprogrammation...)
- Portée lexicale
- Fuites mémoires
class Foo
end
bar = Foo.new
method_name = :something
eval "def bar.#{method_name}; puts 'Hi !'; end"
bar.method(method_name).call
#=> Hi !
Publié par Sobe à 22:39 1 commentaires
Tags : code, meta, programmation, ruby
dimanche 27 avril 2008
MetaTricks : Un petit DSL
Le langage que je vous propose est loin d'être Turing-complet : ce n'est pas le but. Dans sa forme actuelle, il gère les transferts entre les "comptes" de plusieurs personnes grâce à une syntaxe en anglais. Trois verbes disponibles : donner, recevoir et avoir. Les phrases sont formées de la façon suivante :
"Sujet" "Verbe" "Somme" $ [complément]
Avec pour complément facultatif :
"Cibleur" "Second compte"
Il est possible de commenter une ligne en la commençant par "--" (comme en Ada !). Un "cibleur" ('to' ou 'from') désigne un autre compte. Attention, pour des raisons de blocage mental de ma part à l'approche d'une Regexp, la somme d'argent doit être un entier, et non un flottant. Pas de centimes pour les vrais. Ah, oui, et pas de point à la fin des phrases. Il parait que ça sert à rien(.)
Un exemple ?
-- Marie is cool:
Marie gives 5 $ to Peter
Marie has 10 $
Marie receives 15 $ from Peter
Peter gives 10 $ to Simon because he previously borrowed him...
-- Marion is Marie's dark-twin...
Sobe receives 1 $ from Marion
-- But Sobe's a gangsta who gat connectionz so:
Sobe receives 100000 $ like this !
est valable, et donnera :
--------------------
-= Report =-
--------------------
Number of accounts: 5
Marie owns 25.0 $.
Peter lost 20.0 $.
Simon earned 10.0 $.
Sobe earned 100001.0 $.
Marion lost 1.0 $.
C'est loin d'être parfait, mais le corps de l'interprète fait à peine 200 lignes. Je suis juste un peu déçu de ne pas avoir davantage employé les outils de la métaprogrammation : je passe sans doute trop par de l'analyse de chaîne de caractère, opération en soit risquée.
Tout commentaire ou critique vivement apprécié(e).
Publié par Sobe à 21:43 0 commentaires
Tags : code, meta, programmation, ruby
mercredi 23 avril 2008
Ruby : Sécuriser la redéfinition de méthode
Etant un peu angoissé de nature, il y a un truc qui me tracasse en Ruby depuis quelques temps : l'absence de warning à la redéfinition de méthodes existantes. Un exemple ?
class Object
def self.new
puts "Oh dude !"
end
end
a = Array.new 46
#=> **Judgement Day**
Ceci devrait bien vous convaincre de l'utilité d'avertir le programmeur durant le développement. Rappelons aussi que Object.methods dénombre 77 méthodes pour cette racine de tout objet en Ruby...
Du coup, voilà un petit trick qui permet de sécuriser ce point, grâce à la méthode de classe method_added :
class Object
def self.method_added sym
if self.methods.include? sym.to_s then
print "WARNING: method #{sym}" + \\
"of class #{self} redefined\n"
end
end
end
class Integer
def clone
puts "I'm your dark twin !"
end
end
#=> WARNING: method clone of class Integer redefined
Publié par Sobe à 22:38 2 commentaires
Tags : meta, pro, programmation, ruby
lundi 7 avril 2008
MetaTricks : Ciseaux pour enfants
Je n'ai pas la chance d'avoir été sur place mais, miracle du web oblige, les vidéos des différentes présentations sont disponibles (en bonne voire très bonne qualité, avec les slides en direct) à cette page. Merci Confreaks !
La présentation de Giles Bowkett est particulièrement réussie :
Giles Bowkett, dont j'ai régulièrement parlé ici (générateur de MIDI en Ruby, métaprogrammation...), y parle bien sûr de métaprog' et de génération "automatique" de code, le premier étant un outil pour le second.
Il est assez difficile de résumer ce type de présentation en quelques mots, et je vais donc lancer ça en vrac :
- Archimède et mathématiques par les cercles en Grèce.
- Les Rubyistes pratiquent des "langages exotiques" : Scala, Erlang, Haskell, Lisp, Io, Scheme, Smalltalk... mais ne parle pas Grec !
- De Pi "The Circle" à Lambda "The Ultimate" en LISP.
- 3 piliers improbables : Rubinius, Nodebox et "code == data".
- Ruby2ruby
- "Monkeypatch Monkeypatching is Metamonkeypatching"
- Avantages économiques de la génération de code.
- Pub pour "Code Generation in Action"...
- De Java à Rails en passant par LISP (et Perl ! (et Smalltalk !)).
- "Skilled programmers can write better programmers than they can hire."
Publié par Sobe à 22:54 0 commentaires
Tags : meta, programmation, rails, ruby
lundi 18 février 2008
MetaTricks : référence à une méthode
Code :
(Testé sous Windows XP ; Ruby 1.8.6)
class Canard
def initialize name
@nom = name
end
def coin
"Coin coin, I'm #{@nom} !"
end
def Canard.coin2
"Can Can !"
end
end
toto = Canard.new "Dude"
# L'accès à une méthode se fait via +method+
#prenant en argument la référence de la méthode
#(son nom sous forme de string ou de symbol).
hello = toto.method(:coin)
puts hello.call
#(bonus -> arity donne le nombre d'arguments d'une méthode)
puts "To create a new *Canard* needs " \
+ (toto.method(:initialize).arity).to_s \
+ " argument(s)."
# Une liste de références à des méthodes de +Canard+
meths = [:to_s, :to_something_else, :coin, "to_yaml"]
# L'accès se fait ensuite ici encore via +method+
#et l'appel via +call+
meths.each do |meth|
begin
puts "-----------------"
puts "Method #{meth}"
puts (toto.method(meth).call).to_s
rescue
puts "Problem with this method."
next
end
end
Les manipulations possibles sur les méthodes sont peu nombreuses, mais assez puissantes. Ici on a vu call et arity : unbind permet elle de "dissocier" la méthode référencée de son receveur (ce qui donne un objet de la classe UnboundMethod...)
Documentation :
- Classe Method
- Classe UnboundMethod
Publié par Sobe à 01:21 0 commentaires
Tags : code, meta, programmation, ruby
lundi 28 janvier 2008
MetaTricks : Présentation DSL en Ruby
- Vidéo et sources du DSL présenté : chez XAOP
- Slides de la présentation en PDF (recommendés pour suivre la vidéo) : sur RubyForge
La seconde partie concerne plus particulièrement les techniques employées pour la conception de langage dédié (exemple d'une banque) : gestion de self, constantes et méthodes manquantes et personnalisation des opérateurs notamment (et petites allusions à Rails).
Publié par Sobe à 17:24 0 commentaires
Tags : liens, meta, programmation, ruby
jeudi 17 janvier 2008
MetaTricks : define_method
L'exemple suivant est un cas simple. Après avoir défini une méthode mult (multiplication) pour la classe des entiers, je souhaite définir les méthodes mult_by_0, ..., mult_by_10 automatiquement. C'est ce qui est fait dans la première boucle grâce à define_method. Cette méthode prend en entrée le nom de la méthode à définir et lui affecte pour implémentation la closure (ici "mult int").
La vérification que les méthodes d'instances correspondantes ont bien été définies (et pas mult_by_11) est assuré par l'impression de la dernière boucle.
class Integer
def mult by
self * by
end
(0..10).each{|int|
define_method("mult_by_#{int}") do
mult int
end
}
end
(0..11).each{|int|
boo = (1.respond_to? "mult_by_#{int}".to_sym)? \
"" : "don't "
puts "Integers #{boo}respond to mult_by_#{int}"
}
Où est la sorcellerie ?
Publié par Sobe à 21:49 0 commentaires
Tags : code, meta, programmation, ruby
dimanche 13 janvier 2008
MetaTricks : accesseurs
Aujourd'hui, les accesseurs.
Les instructions attr_reader/writer/accessor :nom_variable_instance, même si elles forment une entorse au principe de l'encapsulation, sont très pratiques (et utilisées), et font appel à la métaprogrammation. Pourquoi ? Parce qu'elles implémentent automatiquement les méthodes d'accès en lecture et/ou en écriture pour une variable d'instance donnée (ces méthodes sont alors nommées : nom_variable et nom_variable=).
La preuve :
class Barbare
def initialize a = 1
@alpha = a
end
end
a = Barbare.new.methods.sort
class Barbare
attr_accessor :alpha
end
b = Barbare.new.methods.sort
puts "Methodes ajoutees par attr_accessor = "
puts b-a
#=> [alpha, alpha=]
Où est la sorcellerie ?
Publié par Sobe à 14:10 0 commentaires
Tags : code, meta, programmation, ruby
samedi 12 janvier 2008
Métaprogrammation et Sorcellerie
Dans son très bon article, Giles Bowket essaie de mettre en avant, par diverses citations de Rubyistes reconnus, dont _Why et Russ Olsen (interview - auteur de "Design Patterns in Ruby"), le fait que la métaprogrammation n'est pas un concept obscur et arcanique.
Il y a quelques temps, je vous donnais un lien vers un bon petit tutoriel à ce sujet.
De fait, en Ruby, la métaprogrammation est encouragée, souvent transparente et très utile.
Encouragée, car finalement assez simple syntaxiquement (voir exemples ci-dessous), et surtout déjà implémentée !
Transparente. Si si. Un exemple entre mille : les attr_accessor. Un attr_accessor en début de classe implémente automatiquement les méthodes d'accès en lecture et en écriture d'une variable d'instance donnée. Le saviez-vous ? Pour ma part, j'utilisais les attr bien avant que ce soit le cas !
Très utile. Que celui qui n'a jamais tapé "toto.methods.sort" dans irb me jette la première cacahouète nucléaire. Avant d'avoir la moindre idée de ce qu'était la métaprogrammation ou l'introspection, j'utilisais des méthodes associées à ces concepts (redéfinition de méthodes, inspection des méthodes d'un objet, inclusion d'un module ou non dans une classe, respond_to?, etc...).
Un premier exemple :
Pour montrer l'utilité, et défendre la métaprogrammation contre ses accusations de sorcellerie, ce code implémente 2 fonctionnalités sympas :
- method_added (méthode de classe) réagit ici à la (re)définition de méthodes pour la classe String. Ici par exemple, on souhaite que ma_meth ne soit pas redéfinie ultérieurement, et on soulève donc une exception dans ce cas. Il existe également method_removed se construisant sur le même schéma dans le cas de suppression de méthode (via undef).
- method_missing est appelée en cas d'appel à une méthode d'instance inexistante. Si ça c'est pas utile... A noter qu'il s'agit cette fois d'une méthode d'instance.
class String
def ma_meth
# Pour x raisons, cette methode ne doit
# pas etre modifiee
puts "C'est pas faux..."
true
end
def self.method_added(sym)
if sym == :ma_meth
raise "Pas de modif autorisee pour ma_meth !"
else
puts "Methode #{sym} (re)definie"
end
end
def method_missing(m, *params)
puts "Utilise des methodes existantes ! TOJO !!!"
end
end
a = String.new "toto"
puts "Methode inexistante"
a.lalalalaleeeeere
puts "Redefinition"
class String
def ma_meth
puts "autre..."
false
end
end
#erreur soulevee
a.ma_meth
Dans les références présentées en début d'article, il est dit que la métaprogrammation ne doit pas être désignée par une "pratique avancée". Giles Bowkett propose de dire simplement que c'est une "nouvelle technique" plutôt qu'avancée. Modestement, je serais tentée qu'il s'agit simplement d'une fonctionnalité avancée du langage : cela ne signifie nullement qu'elle serait réservée aux programmeurs "avancés", mais plutôt que le langage est "avancé".
On en reparlera...
Publié par Sobe à 21:01 0 commentaires
Tags : code, liens, meta, programmation, ruby
mardi 18 décembre 2007
Un nouveau tutoriel Ruby : introspection
Il se penche sur un point très puissant du Ruby : l'introspection, c'est à dire la capacité du code à s'analyser lui même. Si ça peut paraître abstrait vu d'ici, je vous conseille vraiment d'aller y jeter un coup d'oeil, car pas mal de choses sont en fait utilisables "au quotidien" (j'y ai mieux compris des choses que j'utilisais depuis assez longtemps...).
Le tuto :
Publié par Sobe à 21:43 0 commentaires
Tags : liens, meta, programmation, ruby