les méthodes d'instance Ruby d'une chaîne et un bloc
Question
Est-il possible de définir une méthode d'instance en rubis d'une chaîne (le nom de la méthode) et un bloc (de contenu de la méthode)?
J'imagine que cela devra utiliser instance_eval (), mais je ne l'ai pas compris comment mélanger encore les deux types de données. Tant la chaîne et le bloc sont déterminés dynamiquement, il travaillerait pour créer le bloc avec la « def # {string} » au début -. Je ne sais pas comment faire
Mon cas d'utilisation est une classe qui représente un fichier de configuration Bacula. Le fichier de configuration peut avoir plusieurs différents types de ressources. Ils sont tous stockés dans une structure de données relativement complexe dans les coulisses (pour d'autres raisons, ce qui simplifie cette structure ne sera pas accomplir ce que je suis à la recherche). Je voudrais les ressources nécessaires pour être rapidement accessibles via des méthodes nommées.
Par exemple, A représente un fichier de configuration, B représente une autre. A a des ressources Directeur, client, Job et B a des messages et directeur.
Dans ce cas, A devrait avoir le directeur des méthodes (), client () et l'emploi () tandis que B a des messages () et directeur (). Chacun d'entre eux retourneraient la ressource pertinente à partir du fichier de configuration respectif de l'objet.
Je sais qu'il ya des moyens plus faciles de le faire (comme la mise en œuvre d'une méthode []), mais à ce stade, je poursuis la solution plus difficile à cause de la curiosité.
La solution
Je pense que ce que vous cherchez est la méthode define_method
sur le module; Cependant, il vous est donc privé devez utiliser class_eval
ou autre chose pour l'exécuter.
body = proc { self * 3 }
name = "triple"
c = Numeric
c.class_eval { define_method(name.to_sym, &body) }
3.triple # 9
Et une méthode avec des arguments:
body = proc { |second| [self * 3, second * 3] }
name = "triple_both"
c = Numeric
c.class_eval { define_method(name.to_sym, &body) }
puts 3.triple_both(5) # [9, 15]
Pour mettre une nouvelle méthode sur un objet singleton (ou Eigenclass, ou tout ce qu'ils sont appelés):
body = proc { puts @meme + @meme + @meme }
name = "meme"
class SwedishChef; def initialize; @meme = "bork"; end; end
sc = SwedishChef.new
(class << sc; self; end).class_eval {
define_method(name.to_sym, &body)
}
sc.meme # borkborkbork
[EDIT (Jörg W Mittag.): Je fixe l'exemple de procédé de singleton]