Je suis aux prises avec du code qui ressemble à l'exemple ci-dessous (mais qui fait quelque chose d'utile). Le bloc qui est passé à def_my_method
est bien sûr créé dans le contexte de la classe, quand je veux l'évaluer dans le contexte de l'instance qui a la méthode de l'instance. Comment puis-je faire cela?Ruby: Passer un bloc à une macro de classe qui définit des méthodes d'instance
module Formatters
# Really useful methods, included in several classes
def format_with_stars(str)
return "*** #{str} ***"
end
end
class Test
include Formatters
STRINGS = ["aa", "bb"]
def self.def_my_method(method_name, another_parameter, &format_proc)
define_method(method_name) do
# In reality, some more complex code here, then...
return STRINGS.map(&format_proc)
end
end
def_my_method(:star_strings, "another_parameter") { |str| format_with_stars(str) }
# Define other methods
end
tt = Test.new
puts tt.star_strings
# Throws undefined method `format_with_stars' for Test:Class (NoMethodError)
Vous n'avez pas besoin du proc enveloppé, vous pouvez simplement faire 'STRINGS.map {| str | instance_exec (str, & format_proc)} '. – sepp2k
@ sepp2k - oh oui, c'est une façon plus claire - merci. J'ai incorporé votre suggestion dans la réponse. (Quelqu'un intéressé - jetez un coup d'œil à l'historique d'édition pour voir mon idée originale d'utiliser un wrapper 'lambda' pour passer à' map'.) – matt
instance_exec semble parfait, mais ce n'est pas le noyau Ruby est-il? Mon Googling suggère qu'il s'agit d'une extension à Object introduite dans Rails 2. Mon exemple simplifié était Ruby pur, bien que le vrai soit Rails - mais Rails 1.2! Donc, je ne vois pas comment utiliser ça. :-( –