2016-03-17 1 views
0

J'essaie de créer dynamiquement des méthodes en fonction du nom fourni comme page-object gem do. Mais dans mon cas c.custom = juste renvoyé l'argument passé, comme l'affectation simple.define_method pour setter ne travaillera pas dans la classe call

Dans ma tâche originale que je dois envoyer appel de méthode avec la valeur fournie comme: self.send(method).send_keys(value)

De plus, je remarque, lorsqu'il est ajouté puts à la ligne "called #{name} with #{value}" et appelé custom à l'extérieur de l'objet comme C.new.custom = 123 il produira les résultats attendus , mais ce n'est toujours pas ce que je veux.

Existe-t-il un moyen de définir la méthode requise, de l'appeler à l'intérieur et à l'extérieur de l'objet?

module M 
    def create(name) 
    define_method("#{name}=") do |value| 
    "called #{name} with #{value}" 
    end 
    end 
end 

class C 
    extend M 
    create(:custom) 
    def initialize(val) 
    puts custom = val 
    end 
end 

C.new('haha') 
+0

@cremno, merci pour le lien, mais ce n'est pas mon problème. Comme avis @engineersmnky - j'assigne à la variable locale là. Je devrais utiliser 'self.custom = 'value'' pour le faire fonctionner. – brbrr

Répondre

1
module M 
    def create(name) 
    define_method("#{name}=") do |value| 
    "called #{name} with #{value}" 
    end 
    end 
end 

class C 
    extend M 
    create(:custom) 
    def initialize(val) 
    puts public_send(:custom=, val) # this is the only change needed 
    end 
end 

C.new('haha') 
# called custom with haha 

Je ne devait changer une ligne dans votre code.

Il y avait deux problèmes avec votre code:

  1. custom = val n'est pas un appel de méthode, il attribue à une variable locale nommée custom. Si vous voulez appeler un setter, vous devez indiquer explicitement que vous appelez une méthode, en fournissant un récepteur explicite: self.custom = val. Voir Why do Ruby setters need “self.” qualification within the class?
  2. Les affectations sont évaluées du côté droit de l'affectation. La valeur de retour d'une méthode setter est ignorée, sauf si vous n'utilisez pas la syntaxe d'affectation, c'est-à-dire public_send. Voir Why does irb echo the right hand side of an assignment instead of the return value in the case of a setter method?
+0

merci pour la bonne réponse, mon cas réel n'a que le 1er problème, donc en utilisant 'self' a résolu mon problème. – brbrr

+0

Serait-il acceptable que vous fermiez cette question en tant que doublon de celle liée à ma réponse? –