2016-08-08 19 views
0

ich mich verärgert mit der folgenden ausführlichen Schreiben in Ruby:Gibt es eine Abkürzung für Ruby Blocks?

polys.each { |poly| poly.edges.each {|edge| draw edge.start, edge.end } } 

(polys ein Array von Polygonen ist, Kanten ist ein Verfahren zum Polygon ein Array von Kanten Rückkehr)

Im Idealfall würde Ich mag an verkürzen, dies zu so etwas wie diese:

polys.each.edges.each { draw _.start, _.end } 

Genauer gesagt würde ich gerne wissen:

  • Wie könnten wir einen method_missing hack schreiben wie bei den ersten? (Beim Aufrufen mit einer fehlenden Methode könnte der Enumerator diese Methode für jedes von der Enumeration zurückgegebene Element aufrufen.)
  • Gibt es eine Möglichkeit, die |x| mit einem beliebigen Symbol oder Standardnamen loszuwerden?
+2

Ist es wirklich 'draw edge.start edge.end'? Nicht 'draw edge.start, edge.end'? –

+0

Was Sie tun möchten, ist in Ruby (oder einer anderen Skriptsprache) problematisch, da Ruby bis zur Laufzeit nichts über den Empfänger weiß. Vergleichen Sie [[1,2], [3,4]]. Je {| e | setzt e} 'mit' [[1,2], [3,4]]. je {| _, e | puts e} 'Wie könnte hier ein Standardwert für die Blockvariable (n) verwendet werden? –

+1

Als C-Coder vor vielen Monden bringt "wortreiches Schreiben" ein Lächeln auf mein Gesicht. Obwohl es nicht kürzer ist, könnten Sie es klarer finden, das, was Sie haben, in der offensichtlichen Weise in Methoden zu trennen: 'def draw_edge (edge); Zeichnen Sie edge.start, edge.end; Ende; def draw_poly (Poly); poly.each {| Kante | draw_edge (Kante)}; Ende; def draw_polys (polys) {| poly | draw_poly (Poly)} '. –

Antwort

4

Nr Closest Sie tun können, wäre:

polys.flat_map(&:edges).each { |_| draw _.start, _.end } 

flat_map wird ein Array in ein anderes Array umwandeln und es auf eine Dimension Array abzuflachen. Wenn das Innere eines Blocks eine einzige Methode ohne Parameter aufruft, können Sie die Verknüpfung &:edges verwenden.

Nachdem dies gesagt ist, würde ich näher halten es wahrscheinlich zu Ihrem ursprünglichen Vorschlag, wie es besser lesbar ist:

polys.each do |poly| 
    poly.edges.each {|edge| draw edge.start, edge.end } 
end 

Denken Sie daran, Sie schreiben, wenn Code, aber es ist viel zu lesen, so die Lesbarkeit Trümpfe Prägnanz.

+7

'polys.flat_map (&: Kanten) .each {| Kante | draw (edge.start, edge.end)} 'ist besser, es ist nicht notwendig, beides als separate Methoden abzubilden und abzuflachen. – philomory

+4

Wenn sie eine 'draw_edge'-Methode definieren, können sie einfach' polys.flat_map (&: edges) .each (& method (: draw_edge)) ' – philomory

+0

entsprechend aktualisieren, danke für die Verbesserung! – Martin

Verwandte Themen