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

Ruby/Beispiele (zuletzt geändert am 2007-12-23 22:46:14 durch localhost)