Ruby Sprache - Schwere Sprache Part II

Published: Sat 07 July 2012
By ali In Ruby.

"The well-grounded Rubyist" hat auch eine sehr gute Einführung in Blocks und Procs. Ich bin zwar selbst noch gefühlt meilenweit davon entfernt, Situationen zu erkennen in denen selbst definierte Methoden die Blocks aufnehmen nützlich sein könnten; vielleicht bin ich zu sehr in der Java-Denke drinnen und werde es wohl nie erkennen.
Ob eine Methode einen Block bekommen kann, hängt davon ab ob sie "yield" enthält.

def y_meth
  yield
end
y_meth { puts 'gabba' }
#=> gabba

"yield" kann auch Parameter haben, diese werden in den aufnehmenden Block zwischen Pipe-Characters geschrieben. Alle Regeln für Methodenargumente (Vorbelegung, Sponge-Stern usw.) gelten auch für Blockparameter.

def add_all
  yield 1, 2, 3
end
add_all do |a, b, c|
  a + b + c
end
#=> 6

Der Interpreter springt regelrecht hin und her: Zuerst wird a an add_all übergeben, da dort nur yield steht und a das erste Argument ist, bekommt add_all eine "1" zurück. Was damit gemacht werden soll steht im Block von add_all. Das ist sehr kontraintuitiv, da man es von vielen anderen Programmiersprachen gewohnt ist nur einen Ausführungspfad innerhalb einer Methode zu haben ("man steckt was rein und es kommt was raus"). add_all mit den Parametern für yield kann ja sonstwo definiert sein oder selbst Methodenaufrufe beinhalten, die selbst wieder einen Block benutzen. Oder einen Block in dem yield vorkommt, welcher das geyieldete Element wieder an die ursprüngliche Methode zurückgibt.

class Array
  def give_back
    acc = [] # Das erste e kommt von each bzw. give_back, # das zweite wird an den Block von give_back gegeben.
    each { |e| acc << yield(e) }
    acc
  end
end
[1, 2, 3].give_back { |e| e\*\*2 }
#=> [1, 4, 9]

Dann gehen auch noch mehrere yield-Statements in einer Methode und vieles mehr. Aus genau solchen Gründen sind Blocks für mich größtenteils weiße Flecken in fremdem Sourcecode, weil die Ausdrucksstärke von Ruby wegen solchen Ratespielchen flöten geht.
Was Blocks jetzt genau mit Procs zu tun haben darauf werde ich ein andermal eingehen.

links