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
endUnd 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
