2009-02-10 4 views
30

Welcher Stil wird bevorzugt? Gibt es einen guten Grund für den einen gegen den anderen?Was ist der Unterschied oder der Wert dieser Blockcodierungsstile in Ruby?

Vielen Dank im Voraus!

1) cmds.each do |cmd| 
    end 

2) cmds.each { |cmd| 
    } 

Beispielcode:

cmds = [ "create", "update", "list", "help" ] 

# Block style one 
# 
cmds.each do |cmd| 
    puts "loop1, cmd: #{cmd}" 
end 

# Block style two 
# 
cmds.each { |cmd| 
    puts "loop2, cmd: #{cmd}" 
} 
+0

gibt es keinen Unterschied, die Do/Ende ist nur schöner. auch ich habe deine frage korrigiert –

+0

Danke Iraimbilanja, deine Änderungen ergeben für mich Sinn. –

+0

@Iraimbilanja: Es gibt einen Unterschied, wie in den Antworten beschrieben. –

Antwort

37

Die Schienen-Team und viele andere Rubyisten prefer geschweiften Klammern für eine Zeile Blöcke und do...end für mehrzeilige diejenigen zu verwenden. Der einzige funktionale Unterschied zwischen den beiden besteht darin, dass der Vorrang eines do...end Blocks niedriger ist als der eines {...} Blocks.

+0

Sie sind die gleiche Sache obwohl. Also, wenn Sie geschweifte Klammern verwenden, würden Sie es in einer Zeile wie folgt schreiben: 'cmds.each {| cmd | puts "loop2, cmd: # {cmd}"} ' –

0

Ich glaube nicht, dass es wirklich wichtig ist - es ist nur eine ästhetische persönliche Wahl. Einige Leute bevorzugen, die do...end Version zu verwenden, wenn der Block mehrere Zeilen und die {...} Version benötigt, wenn alles in einer Zeile ist.

13

Die beiden Formen sind gleichwertig.

Der empfohlene Stil besteht darin, die Klammern für einzelne Zeilenblöcke zu verwenden und für mehrzeilige Blöcke das "tun" - "Ende" zu verwenden.

Bearbeiten:Austin Ziegler wies darauf hin (im Kommentar unten), dass die beiden Formen Unterschied Vorrang Ebenen haben: Curly Hosenträger haben höhere Priorität. Wenn Sie also eine Methode ohne Klammern aufrufen, wird ein in {} eingeschlossener Block an das letzte Argument anstelle der aufrufenden Methode gebunden.

Das folgende Beispiel wurde von Austin vorgeschlagen:

def foo 
    yield 
end 

puts foo { "hello" } 

puts foo do 
    "hello" 
end 

Die ersten "puts" druckt "Hallo": foo "Hallo" genannt wird zurückkehren, welche das Argument Puts ist.

Die zweiten Bügel mit einem Fehler:

in `foo': no block given 

Da in diesem Fall der do-Endblock an die Methode setzt bindet.

Nochmals vielen Dank an Austin für die Aufräumung.

+6

Nein, sind sie nicht. foo def Ausbeute Ende setzt foo { "Hallo" } legt foo tun; "Hallo"; Ende Letzteres wird eine Ausnahme auslösen. Ersteres wird nicht (und es wird "Hallo" gedruckt). {} bindet an #foo; do/end bindet an #puts. –

+0

Vielen Dank, dass Sie darauf hingewiesen haben. Ich habe die Antwort bearbeitet und Ihnen den Kredit gegeben. Sie sollten Ihre eigene Antwort wirklich hinzugefügt haben, damit das ursprüngliche Plakat sie als die richtige Antwort markieren konnte. – nimrodm

2

Meistens wird Stil 1 für Mehrlinienblöcke und Stil 2 für Einzeiler verwendet.

Die Syntax do…end ähnelt stark anderen Ruby-Kontrollstrukturen (if, def, class). Wenn Sie also für Blöcke verwenden, bleibt das Erscheinungsbild Ihres Codes konsistent und klar. Aber es funktioniert nicht gut für Einzeiler, weshalb die eckige Version dort bevorzugt wird.

10

Gordons Antwort ist "der Ruby Way", und obwohl es üblich ist, eine Zeile in Klammern zu setzen, ist es nicht erforderlich.

beachten Sie auch die Leichtigkeit, mit der man auf dem resultierenden Wert handeln kann:

cmds.each do |cmd| cmd.upcase! end.sort 

# Now, cmds = ["CREATE", "HELP", "LIST", "UPDATE"] 

Obwohl Sie vielleicht schon sehen, wie {} besser lesbar hier sind, und daher bevorzugt, wenn jemand andere Ihren Code sehen wird:

cmds.each { |cmd| cmd.upcase! }.sort 
+0

zandev, Danke für den zusätzlichen Tipp auf 'end.sort' –

21

nach the "Pickaxe" book (ich bin auf der Suche an der 2. Auflage hier), Gordon richtig: der einzige Unterschied ist, Vorrang:

p.356 (Hervorhebung von mir):

Braces have a high precedence; do has a low precedence. If the method invocation has parameters that are not enclosed in parentheses, the brace form of a block will bind to the last parameter, not to the overall invocation. The do form will bind to the invocation.

Siehe auch S. 168 für ein Beispiel.

1

Konventionell ist die Verwendung von {} für Single-Line-Blöcke reserviert, während do...end für Multi-Line-Blöcke reserviert ist.

Wege, wie {} sind nicht so häufig wie in anderen Sprachen wie C in Ruby verwendet ++ oder Javascript, do...end zu verwenden, wenn die Chance, statt {} gegeben kann Ihren Code besser lesbar für andere Rubyisten helfen zu machen.

Beachten Sie, dass {} Vorrang vor do...end hat.