2010-03-04 16 views
15

J'essaye d'écrire une méthode qui agit comme un setter et prend des arguments supplémentaires en plus de la valeur assignée. exemple idiot:Création d'une méthode setter qui prend des arguments supplémentaires dans Ruby

class WordGenerator 
    def []=(letter, position, allowed) 
    puts "#{letter}#{allowed ? ' now' : ' no longer'} allowed at #{position}" 
    end 

    def allow=(letter, position, allowed) 
    # ... 
    end 
end 

il l'écriture comme des œuvres indexeur et je peux l'appeler comme ceci:

gen = WordGenerator.new 

gen['a', 1] = true 
# or explicitly: 
gen.[]=('a', 1, true) 

Mais lorsque je tente un des éléments suivants, l'interprète se plaint:

gen.allow('a', 1) = false # syntax error 
gen.allow=('a', 1, false) # syntax error 

Pourquoi ce travail ne fonctionne-t-il pas?

+0

liés/double: http://stackoverflow.com/questions/9280623/setter-method-assignment-with-multiple-arguments – kotique

Répondre

16

Cela ne fonctionne pas car l'analyseur ne le permet pas. Un signe égal est autorisé dans les expressions du formulaire identifier = expression, expression.identifier = expression (où l'identificateur est \w+), expression[arguments] = expression et expression.[]= arguments et en tant que partie d'un littéral de chaîne ou de symbole ou caractère (?=). C'est tout.

gen.send(:allow=, 'a', 1, false) fonctionnerait, mais à ce stade, vous pourriez aussi bien donner à la méthode un nom qui n'inclut pas =.

+0

Merci. Chose amusante est-ce que ça permet des trucs comme 'def seed = (value) end; gen.seed = (1) '. Je m'attendais à ce que 'seed =' soit l'identifiant, mais (si j'ai bien compris vos règles) ça va comme: [gen/expr]. [Seed/identifier] = [(1)/expr]. Cela expliquerait pourquoi il échoue avec plus d'un argument - (a) est une expression, mais (a, b) ne l'est pas! En supposant que cela soit vrai, comment 'gen. [] = (' A ', 1, true)' fonctionne-t-il? –

+0

'. [] =' Est un autre cas particulier que j'ai oublié dans ma liste ci-dessus (avec 'expression [comma_seperated_expressions] = expression', ce qui bien sûr fonctionne aussi). – sepp2k

6

Je suis tombé sur ceci et ai décidé de passer mes arguments comme tableau ou hash.

.: par exemple

def allow=(arguments) 
    puts arguments[:letter] 
    puts arguments[:position] 
    puts arguments[:allowed] 
end 

object.allow={:letter=>'A',:position=>3,:allowed=>true}