2010-03-04 11 views
15

Ich versuche, eine Methode schreiben, die als Setter fungiert und einige zusätzliche Argumente neben dem zugewiesenen Wert. Dumme Beispiel:Erstellen einer Setter-Methode, die zusätzliche Argumente 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 

es als Indexer Werke schreiben, und ich kann es so nennen:

gen = WordGenerator.new 

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

Aber wenn ich eine der folgenden Bedingungen versuchen, der Dolmetscher klagt:

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

Warum funktioniert das nicht, fehlt mir das Offensichtliche?

+0

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

Antwort

16

Es funktioniert nicht, weil der Parser es nicht erlaubt. Ein Gleichheitszeichen ist in Ausdrücken des Formulars identifier = expression, expression.identifier = expression zulässig (wobei der Bezeichner \w+ ist), expression[arguments] = expression und und als Teil eines Strings oder Symbols oder Zeichenliterals (?=). Das ist es.

gen.send(:allow=, 'a', 1, false) würde funktionieren, aber an diesem Punkt können Sie der Methode auch einen Namen geben, der keine = enthält.

+0

Danke. Lustige Sache ist, es erlaubt Sachen wie 'Def Seed = (Wert) Ende; gen.samen = (1) '. Ich hätte erwartet, dass 'seed =' der Bezeichner ist, aber (wenn ich deine Regeln richtig verstanden habe), sieht es so aus: [gen/expr]. [Seed/identifier] = [(1)/expr]. Dies würde erklären, warum es mit mehr als einem Argument versagt - (a) ist ein Ausdruck, jedoch (a, b) nicht! Angenommen dies gilt, wie funktioniert 'gen. [] = (' A ', 1, true)'? –

+0

'. [] =' Ist ein weiterer Sonderfall, den ich oben in meiner Liste vergessen habe (zusammen mit 'expression [comma_seperated_expressions] = Ausdruck', was natürlich auch funktioniert). – sepp2k

6

Ich bin darauf gestoßen und habe beschlossen, meine Argumente als Array oder Hash zu übergeben.

Z. B .:

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

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