Exceptions
def teile(a, b)
raise ZeroDivisionError, "Division durch null" if b.zero?
a / b
end
begin
puts teile(10, 2)
puts teile(1, 0)
rescue ZeroDivisionError => e
puts "Fehler: #{e.message}"
else
puts "kein Fehler"
ensure
puts "ensure läuft immer"
end
def versuche
yield
rescue TypeError, ArgumentError => e
puts "#{e.class}: #{e.message}"
end
versuche { Integer("x") }
versuche { 1 + nil }
versuche { [1, 2].fetch(9) } rescue puts "IndexError (Modifikator-rescue)"
puts (Integer("zzz") rescue -1)
versuche = 0
begin
versuche += 1
raise "kaputt" if versuche < 3
puts "klappte im Versuch #{versuche}"
rescue
retry # erneut versuchen
endAusgabe
5 Fehler: Division durch null ensure läuft immer ArgumentError: invalid value for Integer(): "x" TypeError: nil can't be coerced into Integer IndexError (Modifikator-rescue) -1 klappte im Versuch 3
Fehlerklassen bilden eine Hierarchie: Exception > StandardError > ArgumentError, TypeError, NameError, ZeroDivisionError, IOError ... rescue ohne Klasse fängt StandardError. Fange nie Exception pauschal.
class AppFehler < StandardError; end
class NichtGefunden < AppFehler
def initialize(was) = super("#{was} nicht gefunden")
end
begin
begin
raise NichtGefunden, "Nutzer 7"
rescue AppFehler => e
raise RuntimeError, "umgepackt" # Ursache wird automatisch gemerkt
end
rescue => e
puts "#{e.message} <- #{e.cause.class}: #{e.cause.message}"
end
x = catch(:fertig) do
10.times { |i| throw :fertig, i if i == 3 }
:nie
end
puts xAusgabe
umgepackt <- NichtGefunden: Nutzer 7 nicht gefunden 3
Dateien
require "tmpdir"
Dir.mktmpdir do |dir|
pfad = File.join(dir, "demo.txt")
File.write(pfad, "Zeile 1\nZeile 2\n")
File.open(pfad, "a") { |f| f.puts "Zeile 3"; f.print "Zeile 4\n" }
puts File.read(pfad).length
p File.readlines(pfad, chomp: true)
File.foreach(pfad) { |z| print z.length, " " }
puts
File.open(pfad) do |f|
puts f.gets
puts f.readline
p f.eof?
end
p File.exist?(pfad), File.file?(pfad), File.directory?(dir), File.size(pfad)
p File.basename(pfad), File.extname(pfad), File.basename(pfad, ".txt"), File.dirname("/a/b/c.rb")
Dir.mkdir(File.join(dir, "unter"))
File.write(File.join(dir, "unter", "x.rb"), "")
p Dir.glob("**/*", base: dir).sort
File.delete(pfad)
p File.exist?(pfad)
endAusgabe
32 ["Zeile 1", "Zeile 2", "Zeile 3", "Zeile 4"] 8 8 8 8 Zeile 1 Zeile 2 false true true true 32 "demo.txt" ".txt" "demo" "/a/b" ["demo.txt", "unter", "unter/x.rb"] false
Das Block-Muster (File.open(...) { |f| ... }) schließt die Datei automatisch.
JSON, CSV und YAML
require "json"
require "csv"
require "yaml"
daten = { "name" => "Mia", "alter" => 17, "hobbys" => ["Lesen", "Judo"], "adresse" => nil }
json = JSON.generate(daten)
puts json
puts JSON.pretty_generate(daten)
zurueck = JSON.parse(json)
puts zurueck["hobbys"][1]
sym = JSON.parse(json, symbolize_names: true)
puts sym[:name]
begin
JSON.parse("{kaputt")
rescue JSON::ParserError
puts "ungültiges JSON"
end
puts [1, "a", nil, true].to_json, { a: 1 }.to_json
csv = "name,punkte\nMia,120\nTom,80\n"
tabelle = CSV.parse(csv, headers: true)
tabelle.each { |z| puts "#{z['name']}: #{z['punkte']}" }
puts CSV.generate { |c| c << ["x", "a,b"]; c << [1, 2] }
puts({ "titel" => "Test", "liste" => [1, 2] }.to_yaml)
p YAML.load("a: 1\nb:\n - x\n - y\n")Ausgabe
{"name":"Mia","alter":17,"hobbys":["Lesen","Judo"],"adresse":null}
{
"name": "Mia",
"alter": 17,
"hobbys": [
"Lesen",
"Judo"
],
"adresse": null
}
Judo
Mia
ungültiges JSON
[1,"a",null,true]
{"a":1}
Mia: 120
Tom: 80
x,"a,b"
1,2
---
titel: Test
liste:
- 1
- 2
{"a"=>1, "b"=>["x", "y"]}Reguläre Ausdrücke
text = "Mia (mia@example.com) und Tom (tom@test.de)"
p text =~ /\w+@\w+\.\w+/
p text.scan(/\w+@\w+\.\w+/)
if (m = text.match(/(?<name>\w+) \((?<mail>[^)]+)\)/))
puts "#{m[:name]} -> #{m[:mail]}"
end
p "2025-03-15".match?(/\A\d{4}-\d{2}-\d{2}\z/)
puts "a1b22c333".gsub(/\d+/) { |z| "<#{z.length}>" }
puts "Hallo Welt".sub(/(\w+) (\w+)/, '\2 \1')
p "a, b;c".split(/[,;]\s*/)
p $~.nil?, "x" !~ /y/
if "Datum: 15.03.2025" =~ /(\d+)\.(\d+)\.(\d+)/
puts "#{$3}-#{$2}-#{$1}"
endAusgabe
5 ["mia@example.com", "tom@test.de"] Mia -> mia@example.com true a<1>b<2>c<3> Welt Hallo ["a", "b", "c"] true true 2025-03-15
Zeit und Datum
require "time"
require "date"
t = Time.utc(2025, 3, 15, 14, 30, 0)
puts t, t.year, t.strftime("%d.%m.%Y %H:%M"), t.wday, t.yday, (t + 86400).day
puts Time.parse("2025-03-15 10:00:00 UTC").hour
d = Date.new(2025, 3, 15)
puts d + 20, d >> 1, d.saturday?, d.strftime("%A"), (Date.new(2025, 12, 24) - d).to_i
puts Date.valid_date?(2025, 2, 30), Date.leap?(2024)Ausgabe
2025-03-15 14:30:00 UTC 2025 15.03.2025 14:30 6 74 16 10 2025-04-04 2025-04-15 true Saturday 284 false true
Merke
begin / rescue / else / ensure / end,raise,retry; eigene Fehlerklassen vonStandardError- Dateien:
File.read/write/open/foreach, Block schließt automatisch json,csv,yamlgehören zur Standardbibliothek- Reguläre Ausdrücke:
=~,match,scan,gsubmit benannten Gruppen TimeundDatefür Zeitrechnung
Aufgabe
Lies eine CSV mit Namen und Punkten, berechne den Durchschnitt und schreibe das Ergebnis als JSON.