2010-03-04 23 views
15

Estoy tratando de escribir un método que actúe como un setter y tome algunos argumentos adicionales además del valor asignado. ejemplo tonto:Crear un método setter que tome argumentos adicionales en Ruby

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

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

escritura como funciona un indexador y puedo llamarlo así:

gen = WordGenerator.new 

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

Pero cuando intento alguno de los siguientes, el intérprete se queja:

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

¿Por qué no funciona esto, me estoy perdiendo lo obvio?

+0

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

Respuesta

16

No funciona porque el analizador no lo permite. Se permite un signo igual en las expresiones del formulario identifier = expression, expression.identifier = expression (donde el identificador es \w+), expression[arguments] = expression y expression.[]= arguments y como parte de una cadena o símbolo o carácter literal (?=). Eso es.

gen.send(:allow=, 'a', 1, false)gen.send(:allow=, 'a', 1, false) funcionaría, pero en ese punto también podría darle al método un nombre que no incluya un =.

+0

Gracias. Lo curioso es que permite cosas como 'def seed = (value) end; gen.seed = (1) '. Hubiera esperado que 'seed =' fuera el identificador, pero (si entendí las reglas correctamente) es como: [gen/expr]. [Seed/identifier] = [(1)/expr]. Esto explicaría por qué falla con más de un argumento: (a) es una expresión, ¡sin embargo (a, b) no lo es! Suponiendo que esto se cumpla, ¿cómo funciona 'gen. [] = (' A ', 1, verdadero)'? –

+0

'. [] =' Es otro caso especial que olvidé en mi lista anterior (junto con 'expression [comma_seperated_expressions] = expression', que por supuesto también funciona). – sepp2k

6

Me he encontrado con esto y he decidido pasar mis argumentos como una matriz o hash.

ej .:

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

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