Montag, 8. September 2014

Editoren für REXX, Teil 2: vim

Mittlerweile habe ich ein wenig vim (www.vim.org) in Bezug auf REXX experimentiert. Dieser Editor scheint mir etwas besser zur REXX-Kodierung geeignet zu sein. Folgendes ist mir aufgefallen:

  • Die Syntaxhervorhebung funktioniert fast perfekt: Verschachtelte Kommentare werden korrekt behandelt, alle Schlüsselwörter scheinen erkannt zu werden, wobei auch der Kontext berücksichtigt wird. Zeilenfortsetzungszeichen werden mit einem eigenen Stil angezeigt. Zeichenketten werden zuverlässig abgegrenzt. Bislang habe ich nur kleine, unbedeutende Fehler entdeckt (bei if \ wird das if nicht mehr als Schlüsselwort erkannt; in mehrzeiligen Konstrukten kann es vorkommen, dass eine schließende Klammer falsch hervorgehoben wird).
  • Die ctags-basierte Anzeige der Programmstruktur funktioniert etwas zuverlässiger als unter jEdit. Die schon genannten Einschränkungen, die ctags bei REXX mitbringt, gelten natürlich auch hier.

Es lohnt sich also meines Erachtens, sich mit vim zu befassen, wenn man in REXX kodiert.

Mittwoch, 13. August 2014

Editoren für REXX, Teil 1: jEdit

Ein nicht zu vernachlässigender Faktor im »Ökosystem« einer Programmiersprache ist die Unterstützung durch Editoren – ist es doch diese Komponente, in der die meiste Arbeit erledigt wird. Für REXX ist die Situation da leider nicht optimal, zumindest soweit ich sie bisher erkundet habe. Es soll zunächst eine kurze Information zu jEdit (http://www.jedit.org) geben.

jEdit kennt einen Dateityp »objectrexx«. Dieser leistet Syntaxhervorhebung für REXX-Dateien, allerdings recht unvollständig. Zum Beispiel wird bei Kommentaren die Schachtelung nicht beachtet; viele Schlüsselwörter werden nicht hervorgehoben (anscheinend die abhängigen Schlüsselwörter, die nur dann als Schlüsselwörter gelten, wenn ein anderes Schlüsselwort vorausgeht). Kleine Probleme gibt es auch, wenn es darum geht, das Ende einer Zeichenkette zu bestimmen.

Automatische Einrückungen werden im Modus »objectrexx« zum Großteil sinnvoll vorgenommen. Das ist sehr angenehm.

Mit Hilfe der jEdit-Erweiterung CtagsSideKick gelingt eine rudimentäre Auf‌listung der Unterprogramme, sodass man per Mausklick dorthin navigieren kann. Diese Lösung basiert auf ctags, das zurzeit wohl noch keine mit ::routine definierten Unterprogramme listen kann. Das ist schade. Dazu kommt, dass bei komplexeren Programmen die Unterprogrammliste einfach nicht mehr angezeigt wird. Ich vermute, dass das ein Problem in CtagsSideKick ist, denn vim kann die Liste basierend auf dem gleichen ctags durchaus anzeigen.

Trotz der genannten Probleme ist jEdit trotzdem eine brauchbare Lösung zur Erstellung von REXX-Programmen.

Mittwoch, 6. August 2014

REXX-Befehle direkt in der Kommandozeile

Wie viele andere Skriptsprachen auch unterstützt OORexx die Übergabe von REXX-Befehlen direkt auf der Kommandozeile. Der zuständige Schalter ist -e. Es lässt sich also folgendermaßen eine Berechnung durchführen:

rexx -e "say 12 * 12"

Schnell mal eine Zahl nach hexadezimal konvertieren:

rexx -e "say d2x(153)"

(Die Funktion d2x wandelt eine Dezimalzahl in ihre hexadezimale Darstellung um.)

Oder die ersten drei Zeichen einer Datei hexadezimal ausgeben:

rexx -e "say c2x(charin('maqaf.odt', , 3))"

(charin liest Zeichen aus einer Datei. Der erste Parameter ist der Dateiname, der zweite, der hier ausgelassen ist, gibt die Position an, ab der gelesen werden soll; hier vom Anfang der Datei an. Der dritte Parameter ist die Zahl der zu lesenden Zeichen. c2x wandelt diese drei Zeichen dann in ihre Hexadezimaldarstellung um.)

Montag, 4. August 2014

REXX und der Shebang

Unter Linux ist es üblich, Skripte mit einer Shebang-Zeile beginnen zu lassen. In dieser Shebang-Zeile wird dem Betriebssystem mitgeteilt, mit welchem Interpreter das Skript zu starten ist. Eine solche Zeile könnte so aussehen:

#!/usr/bin/env ruby

Die Zeichenfolge #! nennt man Shebang. Danach schaut das Betriebssystem. In den meisten Skriptsprachen ist das Doppelkreuz wohl nicht ganz zufällig das Kommentarzeichen, sodass diese Zeile vom Interpreter nicht als eine reguläre Programmzeile gelesen wird.

REXX verwendet allerdings nicht das Doppelkreuz als Kommentarzeichen, sondern -- für einzeilige und /* … */ für mehrzeilige Kommentare. Zumindest in Open Object Rexx (nennen wir es ab heute OORexx) funktioniert der Shebang aber trotzdem. Ein Skript darf also so beginnen:

#!/usr/bin/env rexx

Linux findet dann den richtigen Interpreter und dieser beschwert sich nicht über die eigentlich ungültige Syntax der ersten Zeile. Man kann diese Zeile auch drinlassen, wenn das Skript unter Windows ausgeführt wird. Auch die Windows-Version von OORexx ignoriert sie.

Freitag, 1. August 2014

Neue Ufer: REXX

Beruflich habe ich mittlerweile mit REXX zu tun bekommen. Dabei handelt es sich um eine Skriptsprache, die schon einiges älter ist als die, die heute weit verbreitet sind. Dennoch (oder: deshalb?) gibt es einige interessante Ansätze darin.

Die Variante von REXX, mit der ich arbeite ist Open Object Rexx (www.oorexx.org), wie der Name vermuten lässt, eine quelloffene, objektorientierte Fassung von REXX.

Heute werde ich noch nicht viel dazu schreiben; nur »Hello, world!« wollte ich kurz zum Besten geben. Es handelt sich um das kürzeste Hello-world-Programm, das mir bekannt ist:

say 'Hello, world!'

Montag, 5. März 2012

Zurücksetzen einer Textdatei in Free Pascal

Die normale Prozedur zum Verändern der Schreib-/Leseposition in Free Pascal ist Seek. Diese Prozedur kann allerdings nicht auf Textdateien angewendet werden. Über einen Unweg kann aber auch die Schreib-/Leseposition in Textdateien gesetzt werden. Zum Beispiel auf den Anfang der Datei:

FileSeek(GetFileHandle(f), 0, fsFromBeginning);

Dabei ist f natürlich die geöffnete Datei. Alle Symbole finden sich in SysUtils.

Mittwoch, 1. Februar 2012

Lazarus 0.9.30.2

Das habe ich eine Zeit lang nicht mitbekommen: Mittlerweile gibt es Lazarus in der Version 0.9.30.2. Die wesentliche Neuerung scheint zu sein, dass Lazarus jetzt auf der Version 2.4.4 von FPC aufbaut.

Donnerstag, 20. Oktober 2011

Ubuntu 11.10 kann nicht heruntergefahren werden

Nach der Aktualisierung von Ubuntu 11.04 auf 11.10 gab es einige Unstimmigkeiten auf meinem System. Zwei besonders auffallende Dinge waren, dass erstens das Menü zum Herunterfahren des Systems nicht mehr zur Verfügung stand (der Startknopf in der Systemleiste war verschwunden) und zweitens zahlreiche Piktogramme fehlten. Die Lösung war aber einfach:
  1. In der Systemleiste den Benutzer anklicken.
  2. »Benutzerkonten …« auswählen.
  3. »Alle Einstellungen« anklicken. Diese ersten drei Schritte waren nur ein Umweg, um an das Einstellungsmenü zu kommen, das ja fehlt, wenn der Startknopf nicht vorhanden ist.
  4. »Darstellung« anwählen.
  5. Das Thema einmal wechseln, zum Beispiel von Ambiance auf Radiance. Und wieder zurück. Jetzt sollte schon der Startknopf erscheinen, einige der fehlenden Piktogramme sind nach dieser Operation auch vorhanden.
  6. Neustart des Rechners. Nun finden auch die restlichen Piktogramme den Weg auf die Oberfläche. Eventuell reicht auch ein Neuanmelden.
Der Trick ist also im Wesentlichen der, dass man einmal das Oberflächenthema zum Neuladen zwingt.

Dienstag, 24. Mai 2011

FPC: Auffüllen einer Zahl mit Nullen

Bei der Umwandlung von Ganzzahlen in Zeichenketten wird manchmal gewünscht, dass nach links bis zu einer bestimmten Länge mit Nullen aufgefüllt wird. Das lässt sich in Free Pascal mit der Funktion AddChar aus den StrUtils lösen. Ein Beispiel:

AddChar('0', IntToStr(123), 12)

Dieser Aufruf hätte die Zeichenkette »000000000123« zum Ergebnis. Man gibt also das Zeichen, mit dem aufgefüllt werden soll, an, dann die Zeichenkette, dann die gewünschte Länge.

Mittwoch, 11. Mai 2011

FPC: Ungenauigkeiten bei MinutesBetween

MinutesBetween (aus DateUtils) liefert manchmal ein Ergebnis, das um 1 vom erwarteten Ergebnis abweicht. So kann der Unterschied zwischen zwei TDateTime-Werten, die genau eine Minute auseinanderliegen, von der Funktion auch mal mit 0 angegeben werden. Der Grund dafür liegt in der üblichen Ungenauigkeit von Fließkommaoperationen.

Genauer ist nach meinen Erfahrungen in der Regel folgende Konstruktion:

Round(MinuteSpan(t1, t2))

Dabei sind t1 und t2 eben zwei TDateTime-Werte. Hier ist allerdings der aktuelle Rundungsmodus zu beachten, der von Round benutzt wird.

Mittwoch, 6. April 2011

Formatierung von Fließkommazahlen

Allgemein bekannt dürfte sein, dass Fließkommazahlen bei der Ausgabe mit Write(Ln) durch Angabe von Feldbreite und Anzahl der Nachkommastellen formatiert werden können. Diese Angaben werden mit Doppelpunkten an den auszugebenden Wert angehängt. Zum Beispiel liefert

WriteLn(1.234:4:2);

die Ausgabe 1.23. Das Ausgabefeld ist dabei vier Zeichen breit, die Anzahl der Nachkommastellen 2.
Möchte man den gleichen Mechanismus nun nicht direkt für die Ausgabe verwenden, sondern das Ergebnis als Zeichenkette haben, so lässt sich das auch bewerkstelligen. Hierzu verwendet man die Str-Prozedur. Wenn s eine String-Variable ist, so lässt sich darin die formatierte Zahl so abspeichern:

Str(1.234:4:2, s);

Samstag, 13. November 2010

MD5-Summen in Free Pascal

Free Pascal bringt eine Bibliothek mit, die das Erstellen von MD5-Summen sehr einfach macht. Man bindet die Unit MD5 ein und kann dann folgendes schreiben:

s := MD5Print(MD5String('Hallo, Welt!'));

s ist dabei ein String. MD5String erzeugt aus einem Eingabe-String (hier »Hallo, Welt!«) einen Wert vom Typ TMD5Digest. Dieser wird dann von MD5Print in den Ausgabe-String umgewandelt. Möchte man die MD5-Summe über eine ganze Datei bilden, so steht statt MD5String auch MD5File zur Verfügung.

Samstag, 30. Oktober 2010

Viele Fenster in der Lazarus-IDE

Unter Ubuntu (und vermutlich auch anderen Linux-Distributionen) öffnet Lazarus viele eigenständige Fenster. Jedes hat einen Eintrag in der Leiste am unteren Bildschirmrand, das die laufenden Applikationen listet. Da kann es dann schon mal eng werden. Abhilfe schafft es hier, Lazarus einfach auf einer eigenen Arbeitsfläche (Desktop) zu starten. Standardmäßig öffnet Ubuntu ja gleich zwei davon – einen, auf dem ich normalerweise arbeite, und einen zweiten, den ich für Lazarus nutzen kann.

Dienstag, 13. Juli 2010

wxRuby unter Ubuntu 10.04

Unter Ubuntu 10.04 funktioniert das normale wxRuby-Gem in der Version 2.0.1 leider nicht. Es lässt sich zwar installieren, aber es lässt sich dann nicht laden. Man kann aber hier eine Version herunterladen, die für Ubuntu kompiliert wurde. Man wechselt dann in das Verzeichnis, in dem man die gem-Datei abgespeichert hat, und gibt ein:

sudo gem install wxruby-2.0.1-x86-linux -l

Auf diese Weise erreicht man die Installation der lokal vorgehaltenen gem-Datei.

Freitag, 25. Juni 2010

ocra statt rubyscript2exe

Ein weiteres Problem ist mir im Zusammenhang mit dem neuen RubyInstaller für Windows und rubyscript2exe aufgefallen. rubyscript2exe kann keine Module einbinden, die per rubygems geladen werden, da die mit dem neuen RubyInstaller ausgelieferte Version von rubygems nicht mit rubyscript2exe kompatibel ist.

Eine Lösung für rubyscript2exe habe ich diesmal nicht gefunden. Empfohlen wird der Umstieg auf zum Beispiel ocra. Das ist nicht schwer:

gem install ocra

Danach kann man folgendermaßen sein Programm packen:

ocra myscript.rb

Um eine Anwendung ohne Kommandofenster zu erzeugen (also eine, die über rubyw läuft), lautet das Kommando so:

ocra --windows myscript.rb

Von der oben verlinkten Seite aus gelangt man auch zur Dokumentation von ocra, die weitere Optionen erklärt.

Anzumerken ist, dass Programme, die auf wxRuby basieren, mit ocra sehr viel kleinere EXE-Dateien ergeben als mit rubyscript2exe. Schön!

Donnerstag, 17. Juni 2010

MP3-Infos in Ruby

Vor kurzem wollte ich aus MP3-Dateien programmatisch die Dauer des Musikstücks auslesen. Dazu habe ich eine Ruby-Bibliothek gefunden: ruby-mp3info (http://rubyforge.org/projects/ruby-mp3info/), auch verfügbar als Gem mit dem gleichen Namen.

Mithilfe dieser Bibliothek ist es ein Leichtes, die Spieldauer einer MP3-Datei zu ermitteln.

require 'rubygems'
require 'mp3info'
Mp3Info.open('test.mp3') { |mp3|
  p mp3.length
}

ruby-mp3info ist vollständig in Ruby geschrieben, sollte also auf jeder Plattform sofort lauffähig sein.

Mittwoch, 16. Juni 2010

rubyscript2exe-Problem

Die offizielle Version von rubyscript2exe läuft nicht ohne Weiteres unter Ruby 1.8.7. Es kommt ein TypeError, da das Skript $0 nicht modifizieren darf. Aber natürlich hat sich schon jemand des Problems angenommen und eine korrigierte Version von rubyscript2exe zur Verfügung gestellt: http://github.com/cowlibob/rubyscript2exe

Dienstag, 15. Juni 2010

Unicode-Umwandlungen auf der Kommandozeile

Manchmal habe ich UTF-8-kodierte Zeichen hexadezimal vor mir. Will ich dann das entsprechende Zeichen nachschlagen, ist das nicht so einfach, weil aus der UTF-8-Transformation die tatsächliche Zeichennummer nicht direkt ersichtlich ist. Aber mithilfe von Ruby lässt sich da was machen. So kann man die UTF-8-Darstellung in die entsprechende UTF-16-Fassung umwandeln:

ruby -rkconv -e "%|\xc2\xa0|.kconv(Kconv::UTF16, Kconv::UTF8).each_byte { |b| printf '%02X ', b }"

(Das gehört natürlich alles in eine Zeile.)

Vorne setze ich die UTF-8-Bytes ein (hier: \xc2\xa0), als Ergebnis erhalte ich die entsprechenden UTF-16-Bytes. Vertauscht man die Konstanten Kconv::UTF16 und Kconv::UTF8, so erhält man den umgekehrten Weg.

Das Ganze funktioniert so eventuell nur unter Ruby 1.8. Ruby 1.9 verarbeitet Zeichenketten jetzt mitsamt einer mitgeführten Kodierung, sodass die Beispiele vielleicht ganz anders aussehen müssten.

Samstag, 12. Juni 2010

RubyInstaller für Windows fertig

Die neue Version des RubyInstaller für Windows ist fertig (schon seit 6. Juni). So hat man auch unter Windows jetzt eine einfache Möglichkeit, an aktuelle Fassungen von Ruby 1.8.6, 1.8.7 und 1.9.1 zu kommen. Das sollte Ruby unter Windows neuen Auftrieb geben.

Freitag, 11. Juni 2010

Ausschnitte aus Zeichenketten

In Ruby kann man mit regulären Ausdrücken Teile aus Zeichenketten ausschneiden. Man setzt den regulären Ausdruck dazu in eckige Klammern. Nehmen wir folgendes Beispiel:

'Test123Test'[/\d+/]

Das Ergebnis ist die Zeichenkette '123', da der reguläre Ausdruck diesen Abschnitt selektiert. Mit diesem Konstrukt lassen sich manchmal sehr elegant Dinge erledigen.

Passt der reguläre Ausdruck nicht auf die Zeichenkette, so ist der Rückgabewert nil. So würde dieses Beispiel nil ergeben:

'Test'[/\d+/]