Si vous voulez vraiment juste assez ce genre de chose up, pourquoi ne pas envelopper toutes vos méthodes dans une classe comme ceci:
# a container to store all your methods you want to use a hash to access
class MethodHash
alias [] send
def one
puts "I'm one"
end
def two
puts "I'm two"
end
end
x = MethodHash.new
x[:one] # prints "I'm one"
x.two # prints "I'm one"
ou, pour utiliser votre exemple:
# a general purpose object that transforms a hash into calls on methods of some given object
class DelegateHash
def initialize(target, method_hash)
@target = target
@method_hash = method_hash.dup
end
def [](k)
@target.send(@method_hash[k])
end
end
class A
def initialize
@a = DelegateHash.new(self, { 0 => :a })
end
def a()
puts "hello world"
end
def b()
@a[0]
end
end
x = A.new
x.a #=> prints "hello world"
x.b #=> prints "hello world"
Une autre erreur de base que vous avez faite est que vous avez initialisé @a
en dehors de toute méthode d'instance - juste nue à l'intérieur de la définition de A
. C'est un grand moment non-non, parce que ça ne marche pas. Rappelez-vous, dans ruby, tout est un objet, y compris les classes, et le préfixe @
signifie la variable d'instance de tout objet qui est actuellement auto. Dans une définition de méthode d'instance, self
est une instance de la classe. Mais en dehors de cela, juste à l'intérieur de la définition de classe, self
est l'objet de classe - donc vous avez défini une variable d'instance nommée @a
pour l'objet de classe A
, auquel aucune des instances de A
ne peut accéder directement.
Ruby a une raison de ce comportement (les variables d'instance de classe peuvent être très utiles si vous savez ce que vous faites), mais c'est une technique plus avancée.
En résumé, initialisez uniquement les variables d'instance dans la méthode initialize
.
qui est vraiment ce que je essayait d'éviter. Le code que je mettrais dans le lambda peut être un peu brouillon, et j'aurai environ 15 éléments dans le hachage. Cela encombre un peu le code. – Peter
@Peter: Le code est-il plus lâche dans un lambda que dans une méthode? – Chuck
puis passez les noms de méthode comme symboles et utilisez send ou Symbol # to_proc. –