Ruby Beispiele
Ich kenne Ruby erst seit 2 Tagen, also erwartet keine Guru-Version. Es folgt einfach die Umsetzung einer Standard-Aufgabe von Perl in Ruby:
use strict; my $factor = 1.9558; # globale Variable sub DM2EUR { my $fn = shift; open(INP, $fn) || die "+++ $!"; while (<INP>) { # Euro umrechnen: while (/([\d+.]+)\s\DM\b/) { my $euro = sprintf ("%.2f", $1 / $factor); s/[\d.]+(\s+)DM\b/$euro\1EUR/; } # while # Dezimalpunkt in Komma s/(\d+)\.(\d+)/\1,\2/g; print; } close (INP); } chdir ('/home/src/ruby'); &DM2EUR ("t.dat");
class Main # Total OO: Wir brauchen eine Klasse. Name: 1. Buchstabe gross FACTOR=1.9558; # Konstante. Name gross. def dm2eur (fn) # Methode. Name: 1.Buchstabe klein. Parameter: 1.Buchstabe klein f = File.new (fn, 'r'); # lokale Variable: 1.Buchstabe klein f.each_line do |line| # do ... end oder {..} ist ein Block # |line| bedeutet, der Block hat einen Parameter. Wird von each_line versorgt. # each_line erwartet nämlich einen Block mit einem Parameter while line =~ /([\d.]+)\s+DM\b/ do euro = "%.2f" % ($1.to_f / FACTOR); # Explizite Umwandlung in float mittels to_f # % ist ein Operator mit der Funktionalität von sprintf line.sub! (/[\d.]+(\s+)DM\b/, euro + '\1EUR'); # sub! ist eine Methode von String end # while /...DM/ # Dezimalpunkt in Dezimalkomma: line.gsub! (/(\d+)\.(\d+)/, '\1,\2'); print line; end; # each_line f.close; rescue SystemCallError # Simulation von die () mittels Exception $stderr.print "+++ : #${!}"; # #${variable} in ""-Strings wird ersetzt! abort; end; # dm2eur end; # Main Dir.chdir ('/home/src/ruby'); main = Main.new; main.dm2eur ('t.dat');
Ich kenne Ruby schon etwas länger und möchte das Skript etwas verschönern:
FACTOR=1.9558 # Konstante. Name gross. # Methode. Name: 1.Buchstabe klein. Parameter: 1.Buchstabe klein # Eine Klasse ist in Ruby für kleines Skript (wie auch in Perl) nicht nötig def dm2eur(fn) # Parameter: 1.Buchstabe klein File.open(fn) do # File.open in der Blockvariante |f| # f ist das IO-Objekt für die nun offene Datei f.each_line do |line| # do ... end oder {..} ist ein Block # |line| bedeutet, der Block hat einen Parameter. Wird von each_line versorgt. # each_line erwartet nämlich einen Block mit einem Parameter. while line =~ /([\d.]+)\s+DM\b/ do # Explizite Umwandlung in float mittels to_f euro = "%.2f" % ($1.to_f / FACTOR) # % ist ein Operator mit der Funktionalität von sprintf line.sub! (/[\d.]+(\s+)DM\b/, euro + '\1EUR') # sub! ist eine Methode von String end # while /...DM/ # Dezimalpunkt in Dezimalkomma: line.gsub! (/(\d+)\.(\d+)/, '\1,\2') print line end # each_line # f.close ist nicht nötig, wenn File.open mit der Blockvariante benutzt wird. end rescue SystemCallError # Simulation von die () mittels Exception $stderr.print "+++ : #{$!}" # ${variable} in ""-Strings wird ersetzt! abort end # def dm2eur Dir.chdir('/home/src/ruby') dm2eur('t.dat')
Eine weitere Idee, wie man das Problem mehr OO-mäßig löst: -- WinfriedMueller
#Author: Winfried Mueller, www.reintechnisch.de #Date : 20.11.2003 #Klasse Geld: Kann mit Euro und DM umgehen. #z.B. set("10.39 DM" ); set( "9.89 EUR" ) class Geld EUR=1.9558 TRENNER=',' def initialize( betrag="0 DM" ) set( betrag ) end def set ( betrag ) rxpIsDM = /([\d.]+)\s+DM/ rxpIsEUR = /([\d.]+)\s+EUR/ if betrag =~ rxpIsDM @betrag = $1.to_f / EUR elsif betrag =~ rxpIsEUR @betrag = $1.to_f else # andere Formate nicht erlaubt. raise end return self end def to_EUR return sprintf( "%.2f EUR", @betrag ).sub( /\./, TRENNER ) end def to_DM return sprintf( "%.2f DM", @betrag * EUR ).sub( /\./, TRENNER ) end end geld = Geld.new rxpFindeGeld = /([\d.]+\s+(DM|EUR))\b/ File.foreach( 't.dat' ) do |line| line.gsub!( rxpFindeGeld ) do |match| geld.set(match).to_EUR end puts line end
Und hier noch ein t.dat zum testen:
Hier sind 123.49 DM und 1294.03 DM Und hier habe ich 39949.39 DM 10 DM 10.30 DM 7.39 DM 10.49 EUR 9.39 EUR