2010-03-04 10 views
15

Sto provando a scrivere un metodo che funge da setter e prende alcuni argomenti extra oltre al valore assegnato. esempio stupido:Creazione di un metodo setter che richiede argomenti aggiuntivi in ​​Ruby

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

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

scrittura come funziona un indicizzatore e posso chiamare in questo modo:

gen = WordGenerator.new 

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

Ma quando provo una delle seguenti, l'interprete si lamenta:

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

Perché non funziona, mi manca l'ovvio?

+0

correlati/duplicato: http://stackoverflow.com/questions/9280623/setter-method-assignment-with-multiple-arguments – kotique

risposta

16

Non funziona perché il parser non lo consente. Un segno di uguale è consentito nelle espressioni del modulo identifier = expression, expression.identifier = expression (dove identificatore è \w+), expression[arguments] = expression e expression.[]= arguments e come parte di una stringa o simbolo o carattere letterale (?=). Questo è tutto.

gen.send(:allow=, 'a', 1, false) funzionerebbe, ma a quel punto si potrebbe anche solo dare al metodo un nome che non include uno =.

+0

Grazie. La cosa divertente è che permette cose come "def seed = (value) end; gen.seed = (1)'. Mi sarei aspettato che 'seed =' fosse l'identificatore, ma (se ho capito bene le tue regole) è come: [gen/expr]. [Seed/identificatore] = [(1)/expr]. Questo spiegherebbe perché fallisce con più di un argomento - (a) è un'espressione, tuttavia (a, b) non lo è! Supponendo che ciò valga, come funziona 'gen. [] = (' A ', 1, true)'? –

+0

'. [] =' È un altro caso speciale che ho dimenticato nella mia lista sopra (insieme a 'expression [comma_seperated_expressions] = expression', che ovviamente funziona anche). – sepp2k

6

Mi sono imbattuto in questo e ho deciso di passare i miei argomenti come array o hash.

Es .:

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

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