european ruby conference 2011 06. Aug 2010

Die europäische Ruby-Konferenz Euruko kommt 2011 nach Berlin!

 

programming language observation 26. Jun 2010

Wenn Haskell mit seinen Monaden wie Sex mit Kondom ist und Ruby ungeschützten Geschlechtsverkehr darstellt dann ist PHP das programmierprachliche Pendant zu einer schnellen Nummer mit einer abgewrackten Cracknutte.

 

named groups in oniguruma 16. Jun 2010

Ich habe Oniguruma bisher nur in Textmate verwendet. Darüber hinaus findet es aber auch noch bei Ruby 1.9 Verwendung. In diesem Zusammenhang machen dann auch benannte Gruppen Sinn. Wenn man in Ruby 1.8 Gruppen referenzieren möchte dann geht das nur über ihre Position.

m = /(\w+) (\w+)/.match("Kalle Anka")
puts "#{m[1]} gehört zur Familie #{m[2]}"

Das ist praktikabel, aber nicht optimal im Sinne der Lesbarkeit. Wenn man nun die Lesbarkeit verbessert, dann bläht sich der Code auf.

m = /(\w+) (\w+)/.match("Kalle Anka")
vorname = m[1]
nachname = m[2]
puts "#{vorname} gehört zur Familie #{nachname}"

Durch Oniguruma In Ruby 1.9 läßt sich das ganze relativ elegant ausdrücken.

m = /(?<Vorname>\w+) (?<Nachname>\w+)/.match("Kalle Anka")
puts "#{m["Vorname"]} gehört zur Familie #{m["Nachname"]}"

Aus meiner Perspektive erhöht sich nicht nur Lesbarkeit der Ausgabezeile sondern auch die Wartbarkeit des regulären Ausdrucks. Jeder der schonmal einen umfangreicheren regulären Ausdruck erstellt hat und zwei Jahre später nochmal damit in Kontakt gekommen ist, der weiß wie unintuitiv komplexe reguläre Ausdrück sind. Ich denke benannte Gruppen können hier einen sinnvollen Beitrag zur besseren Wartbarkeit liefern. Eine andere Sache ist, dass sich bei mehreren Vergleichen schnell ein Wildwuchs an Variablen ergibt.

var1 = /(?<Vorname>\w+) (?<Nachname>\w+)/.match("Kalle Anka")
var2 = /(?<Strasse>\w+) (?<Hausnummer>\w+)/.match("Entenstrasse 13")
var3 = /(?<Postleitzahl>) (?<Ortschaft>\w+)/.match("368 Ankeborg")
puts("#{var1["Vorname"]} wohnt in der #{var2["Strasse"]} in #{var3["Ortschaft"]}")

Dem läßt sich begegnen indem man die MatchData-Klasse um eine Methode zur Konvertierung in einen Hash erweitertet.

class MatchData
  def to_h
    Hash[*self.names.zip(self.captures).flatten]
  end
end

Dann kommt man mit einer Variable aus.

h = (/(?<Vorname>\w+) (?<Nachname>\w+)/.match("Kalle Anka").to_h) 
h.merge!(/(?<Strasse>\w+) (?<Hausnummer>\w+)/.match("Entenstrasse 13").to_h)
h.merge!(/(?<Postleitzahl>\w+) (?<Ortschaft>\w+)/.match("368 Ankeborg").to_h)
puts("#{h["Vorname"]} wohnt in der #{h["Strasse"]} in #{h["Ortschaft"]}")

Dafür wird das ganze jetzt aber etwas verbose. Wäre es nicht prima, wenn die Hash-Klasse einen Push-Operator besäße?

class Hash
  def <<(other_hash)
    merge!(other_hash)
  end
end

Okay, ich denke so kann man das stehen lassen.

h = /(?<Vorname>\w+) (?<Nachname>\w+)/.match("Kalle Anka").to_h
h << /(?<Strasse>\w+) (?<Hausnummer>\w+)/.match("Entenstrasse 13").to_h
h << /(?<Postleitzahl>) (?<Ortschaft>\w+)/.match("368 Ankeborg").to_h
puts("#{h["Vorname"]} wohnt in der #{h["Strasse"]} in #{h["Ortschaft"]}")
 

ruby's class method going social 15. Jun 2010

class Buerger
  attr_reader :name, :einkommen
  def initialize(name, einkommen)
    @name = name
    @einkommen = einkommen
  end
  def class
    case
      when einkommen > 1844
        return "Oberschicht"
      when (einkommen >= 860 and einkommen <= 1844)
        return "Mittelschicht"
      when einkommen < 860
        return "Unterschicht"
    end
  end
end

buerger = Array.new
buerger << Buerger.new("Maximilian", 5200)
buerger << Buerger.new("Sabine", 1500)
buerger << Buerger.new("Jacqueline", 670)

buerger.each do |buerger|
  puts "#{buerger.name} verdient #{buerger.einkommen} Euro"
  puts "#{buerger.name} ist #{buerger.class}"
end

Siehe hierzu die Studie des Deutschen Instituts für Wirtschaftsforschung.

 

best web development language 12. May 2010

Durch hochwissenschaftliche Untersuchungen komme ich zu folgendem Ranking:

  1. Ruby (Platz 9)
  2. Python (Platz 12)
  3. PHP (Platz 35)
  4. Perl (Platz 39)
  5. Java (Platz 55)
  6. Scala (Platz 124)*

*Hierbei handelt es sich offensichtlich um einen Messfehler, meine Messmethode ist also noch optimierungsbedürftig!

 

1 2 3 ... 5