2010-12-28 3 views
11

In Rubin, können Sie dies tun:Rubin - überwiegende/ermöglicht eine Mehrfachzuordnung (zB `a, b, c = d, e, f ')

d = [1, 2, 3] 
a, b, c = d 

a, b und c, erhalten die Werte 1, 2 bzw. 3.

d, in diesem Fall in einem Array und Rubin weiß, dass es Inhalte zu a, b und c zuzuordnen. Wenn jedoch d ein Fixnum wäre, würde zum Beispiel nur a dem Wert d zugewiesen, während b und cnil zugewiesen wären.

Welche Eigenschaften von d erlauben es für die Mehrfachbelegung verwendet werden? In meiner bisherigen Erkundung konnte ich nur Instanzen von Unterklassen von Array auf diese Weise verhalten.

Antwort

11

Dies ist ein sehr undokumentiertes Feature, und ich würde es mit Vorsicht verwenden, aber hier gehen wir. Aus dem Buch The Language Ruby-Programmierung:

Wenn es mehrere lvalues ​​und nur eine einzige rvalue versucht Ruby die rvalue in eine Liste von Werte erweitern zuzuordnen. Wenn der Wert ein Array ist, wird das Array von Ruby so erweitert, dass jedes Element zu seinem eigenen rvalue wird . Wenn der Wert kein Array ist, aber eine Methode to_ary implementiert, ruft Ruby diese Methode auf und erweitert dann das zurückgegebene Array um .

In Ruby 1.8 ist die to_ary Methode, in Ruby 1.9 Dokumentation sagt, es to_splat nennt, aber ich habe nicht getestet (keine 1.9 in dieser Maschine) Es funktioniert nicht wie erwartet. Also, Sie müssen eine to_ary Methode in Ihrem Objekt definieren.

class Week 
    def to_ary 
    %w(monday tuesday wednesday thursday friday saturday sunday) 
    end 
end 

mon, tue, wed, thu, *weekend = Week.new 

* %w(...) Ist eine spezielle Notation für eine Reihe von Worten, wenn Sie faul sind ['monday', 'tuesday' ...]

+0

schreiben glaube, ich versuchen Rubin! verwendet 1.9. Oder Sie können das vollständig fallen lassen und jQuery RVM verwenden. –

+0

:) Eigentlich ging nach der Antwort auf 'rvm installieren 1.9.1' – Chubas

7

Welche Eigenschaften von d erlauben es für Mehrfachbelegung verwendet werden?

d muss ein Array sein oder in eins umwandelbar sein. IOW es muss entweder eine Instanz der Array Klasse (oder einer ihrer Unterklassen) oder reagieren auf die to_ary Nachricht sein:

def (not_an_array = Object.new).to_ary; [:foo, :bar, :baz] end 

foo, bar, baz = not_an_array 

foo # => :foo 
bar # => :bar 
baz # => :baz 

Beachten Sie, dass dies ein Beispiel eines allgemeineren Muster in Ruby: fast alle Methoden in Rubin, die ein Array erwarten, ein String, ein Integer oder ein Float wird ein Objekt auch akzeptieren, die to_ary reagiert, to_str, to_int oder to_float. Und Ihre eigenen Methoden sollten übrigens auch!

Verwandte Themen