Dienstag, 1. Dezember 2009

FPC: Effizienzsteigerung durch CONST

An verschiedenen Stellen habe ich mittlerweise gelesen, dass die Verwendung von CONST bei der Übergabe von Zeichenketten an Prozeduren und Funktionen eine Geschwindigkeitssteigerung ergeben soll. Das habe ich jetzt mal getestet. Die Rede ist von einer Deklaration wie

PROCEDURE DoSomething(CONST s: ANSIString);

statt

PROCEDURE DoSomething(s: ANSIString);

Und in der Tat: Mit einem Beispielprogramm habe ich eine Effizienzsteigerung um den Faktor 3 gemessen, wenn als Zeichenkette »This is a test.« übergeben wird. Mit längeren Zeichenketten fällt der Effekt noch stärker zugunsten der CONST-Variante aus. Verwendet man CONST, hängt die verbrauchte Zeit nicht von der Länge der Zeichenkette ab. Verwendet man CONST nicht, wächst die verbrauchte Zeit mit der Länge der Zeichenkette.

Muss man also an einer übergebenen Zeichenkette in einer Prozedur oder Funktion nichts ändern, so empfiehlt es sich tatsächlich, diese als CONST zu deklarieren.

Sonntag, 20. September 2009

»Friends of FPC« überarbeitet

Die Free-Pascal-Seite »Friends of FPC« hat vor einiger Zeit einen neuen Betreiber und dann auch ein neues Aussehen bekommen. Schön, dass sich hier wieder etwas tut!

Die Seite findet man hier: http://www.friends-of-fpc.org/

Donnerstag, 6. August 2009

RegExpr unter Linux

Für Free Pascal gibt es ja eine ziemlich gute Bibliothek für reguläre Ausdrücke: RegExpr (kostenfrei erhältlich hier: http://www.regexpstudio.com/). Allerdings benutzt sie die Windows-Unit, sodass sie unter Linux so nicht verwendbar ist. Oder vielleicht doch? Ich habe die USES-Klausel, die die Windows-Unit einbindet, einfach mal auskommentiert (Zeilen 633 und 634) und dann versucht, die Bibliothek zu kompilieren. Und siehe da: Das funktioniert! Der Grund ist, dass die Windows-Unit gar nicht wirklich benutzt wird, wenn die Bibliothek unter FPC kompiliert wird.

Montag, 20. Juli 2009

Zeilen bewegen in Vim

In irgendeinem Editor habe ich mal gesehen, wie eine Tastenkombination zur Verfügung stand, die die aktuelle Zeile eins nach oben oder unten bewegte. Oder anders ausgedrückt: die die aktuelle Zeile mit der darüber oder darunter tauschte. Jetzt habe ich das mal in Vim als Tastaturbelegung »nachprogrammiert«. Folgende zwei Zeilen habe ich meiner ~/.vimrc hinzugefügt:

map <C-J> ddp
map <C-K> ddkP


Strg-J bewegt nun die aktuelle Zeile eins nach unten, Strg-K eins nach oben. Nett.

Montag, 13. Juli 2009

Lesen der Registrierdatenbank

In Free Pascal kann man auf die Windows-Registrierdatenbank zugreifen. Im Folgenden wird der Eintrag »Adapter ID« aus dem Schlüssel »Software\Microsoft\Screensavers\Text3D\Screen 1« im Baum HKEY_CURRENT_USER ausgelesen und angezeigt.

PROGRAM RegistryView;
USES Registry;

VAR
  buffer: ARRAY [0 .. 15] OF Byte;
  count : Integer;
  i     : Integer;
  r     : TRegistry;

BEGIN
  r := TRegistry.Create;
  r.RootKey := HKEY_CURRENT_USER;
  r.OpenKeyReadOnly('Software\Microsoft\Screensavers\Text3D\Screen 1');
  count := r.ReadBinaryData('Adapter ID', buffer, Length(buffer));
  r.Free;
  FOR i := 0 TO count - 1 DO BEGIN
    Write(HexStr(buffer[i], 2), '  ');
    IF (i + 1) MOD 16 = 0 THEN
      WriteLn;
  END;
END.


Die FOR-Schleife sorgt dabei für eine hexadezimale Ausgabe des Puffers.

Samstag, 11. Juli 2009

Rundung in Calc

Gibt man in Calc eine Zahl mit Nachkommastellen in eine Zelle ein, so wird diese Zahl standardmäßig auf zwei Nachkommastellen gerundet dargestellt. Wie lässt sich dieses Verhalten verändern, sodass stattdessen zum Beispiel die Zahl auf eine Ganzzahl gerundet wird?

Die nötige Option befindet sich im Menüpunkt Format => Zellen, im Reiter Zahlen. Im Abschnitt Optionen findet sich eine Einstellung für Nachkommastellen. Diese steht (zumindest bei mir) standardmäßig auf 0, davon sollte man sich aber nicht irritieren lassen, auch wenn eigentlich 2 dort stehen sollte. Man kann die 0 durch eine neue 0 ersetzen und bekommt dann tatsächlich für die vorher selektierten Zellen eine Rundung auf Ganzzahl.

Wichtig ist, dass man hier nur die Anzeige der Werte einstellt. Der Wert selbst bleibt so erhalten, wie man ihn ursprünglich eingegeben hat. Wenn man später das Format wieder auf mehr Nachkommastellen umstellt, so stellt sich heraus, dass Calc sich durchaus noch an die Nachkommastellen erinnert, die vorher da waren.

Mittwoch, 8. Juli 2009

Externe Variablen in Free Pascal

Vor kurzem schrieb ich über die Möglichkeit, das Datum und die Zeit des Kompilierens in einem Free-Pascal-Programm zu hinterlegen ({$I %DATE%} und {$I %TIME%}). Nun kann es vorkommen, dass man diese Daten in einem komplexeren Projekt mit vielen Units verwendet. Angezeigt werden sie zum Beispiel in einer Unit X. Diese Unit wird aber nicht immer neu kompiliert. Nur, wenn sich an der Unit X selbst etwas geändert hat, wird diese ja neu kompiliert. Wenn nicht, dann bleibt die Anzeige von Datum und Uhrzeit auf dem alten Stand.

Man muss nun also einen Teil des Projekts finden, der immer neu kompiliert wird. Das ist die Hauptprogrammdatei. Dann muss man in dieser Hauptdatei Variablen definieren, die Datum und Zeit aufnehmen. Auf diese Variablen kann dann aus der Unit X heraus zugegriffen werden. Hier ein Beispiel.

Das Hauptprogramm:
PROGRAM Test;
USES TestUnit;

VAR
BuildString: String = '[' + {$I %DATE%} + ' ' + {$I %TIME%} + ']';
CVAR; EXPORT;

BEGIN
TestOut;
END.
Die Unit, die Datum und Uhrzeit zur Anzeige bringt:
UNIT TestUnit;

INTERFACE

PROCEDURE TestOut;

IMPLEMENTATION

VAR
BuildString: String; CVAR; EXTERNAL;

PROCEDURE TestOut;
BEGIN
WriteLn('BuildString: ', BuildString);
END;

END.
Hier wird der Einfachheit halber nur eine Variable deklariert, die beides aufnimmt. Entscheidend ist, dass wir im Hauptprogramm die Variable zur Verwendung in anderen Units freigeben. Hier wird das durch CVAR; EXPORT; erreicht. In der Unit, die die Variable dann verwendet, wird die Variable als CVAR; EXTERNAL; deklariert, um anzuzeigen, dass auf eine Definition der Variable in einer anderen Übersetzungseinheit zugegriffen wird.

Montag, 29. Juni 2009

Calc: Erkennung von Zahlen abschalten

Wenn man in OpenOffice.org Calc in eine Zelle eine Zahl eingibt, so erkennt das Programm das und nimmt die Zahl auch als Zahl entgegen und nicht etwa als irgendeinen Text. Das kann in Ausnahmefällen störend sein. Zum Beispiel, wenn man 2- oder 2+ eingeben will. Das macht Calc dann nämlich zu -2 und 2. Man kann aber das Format einer Zelle auch manuell setzen:

Format => Zellen => Zahlen

In dieser Box kann man jetzt unter »Kategorie« »Text« auswählen. Wenn man nun in die Zelle 2- oder 2+ eingibt, so bleibt dieser Text bestehen. Falls man die rechtsbündige Formatierung braucht, die man mit Zahlen normalerweise bekommt, kann man sie einer solchen Zelle immer noch manuell zuweisen.

Donnerstag, 18. Juni 2009

Erstellungsdatum und -zeit mit Free Pascal

Was man nicht so alles Interessantes findet, wenn man Referenzhandbücher liest! Free Pascal kann zum Beispiel Erstellungsdatum und -zeit eines Programms innerhalb des Programms zur Verfügung stellen. Zum Beispiel so:

WriteLn('Date: ', {$I %DATE%});
WriteLn('Time: ', {$I %TIME%});

Hier findet sich die Information, ebenso auch weitere Angaben, die ähnlich erreicht werden können: http://www.freepascal.org/docs-html/prog/progsu38.html#x45-430001.1.38

Mittwoch, 17. Juni 2009

Calc: Manchmal zu hilfsbereit

In OpenOffice.org Calc werden einem bei der Eingabe in eine Zelle normalerweise Texte angezeigt, die man in der gleichen Spalte schon einmal eingegeben hat und die mit dem Text beginnen, den man bereits eingegeben hat. Das kann sehr hilfreich sein. Es kann aber auch zu einem Problem führen: Calc beachtet beim Abgleich nicht die Groß-/Kleinschreibung. Wenn man nun ein Wort bereits kleingeschrieben eingegeben hat und es in einer anderen Zelle noch einmal großgeschrieben tippt, so wird das Wort beim Verlassen der Zelle in Kleinbuchstaben umgewandelt. Hier schlägt die Eingabehilfe zu, was in diesem Fall aber eher problematisch ist.

Der Trick ist, dass man die genannte Vervollständigungsautomatik abschaltet, bevor man das großgeschriebene Wort eingibt. Dies erfolgt unter Extras => Zellinhalte => AutoEingabe. Nachdem man die Zelle fertigeditiert hat, kann man diese Automatik wieder einschalten.

Montag, 15. Juni 2009

GetWorksheetByName

Die TSWorkbook-Klasse gibt einem die enthaltenen Arbeitsblätter zurzeit nur per Index (TSWorkbook.GetWorksheetByIndex). Sucht man nach einem Arbeitsblatt mit einem bestimmten Namen, schreibt man sich einfach eine Funktion:


FUNCTION GetWorksheetByName(workbook: TSWorkbook; name: String):
TSWorksheet;
VAR
i : Integer;
worksheet: TSWorksheet;
BEGIN
result := NIL;
FOR i := 0 TO workbook.GetWorksheetCount - 1 DO BEGIN
worksheet := workbook.GetWorksheetByIndex(i);
IF worksheet.Name = name THEN BEGIN
result := worksheet;
Break;
END;
END;
END;


Die Funktion gibt entweder die gesuchte TSWorksheet-Instanz zurück, oder NIL, wenn kein Arbeitsblatt mit dem Namen existiert.

Samstag, 13. Juni 2009

Editor für Ruby

Bei Skriptsprachen mit ihren oftmals mehrdeutigen syntaktischen Konstrukten stellt sich häufig die Frage, welcher Editor denn damit klarkommt. Was Ruby angeht, habe ich da mit Geany gute Erfahrungen gemacht. Ich habe bei Geany noch keine fehlerhafte Syntaxhervorhebung gesehen und auch die Übersicht über die Klassen und Methoden in einer Datei funktioniert gut. Geany gibt es hier: http://www.geany.org/

Freitag, 12. Juni 2009

Dateilisten bei TFTPSend in Synapse

Synapse ist eine ziemlich praktische TCP/IP-Bibliothek für Free Pascal, vor allem was die Programmierung von TCP/IP-Clients angeht. Zu Synapse geht’s hier: http://synapse.ararat.cz/doku.php

Ein Verhalten der Synapse-Klasse TFTPSend, das für mich nicht gleich offensichtlich war, ist folgendes: Setzt man bei der Methode List den NameList-Parameter auf TRUE, dann wird die Eigenschaft FTPList nicht gefüllt. Woher bekommt man dann das angeforderte Verzeichnis? Lösung: Man muss auf die Eigenschaft DataStream zurückgreifen, um an die Dateiliste zu kommen.

Mittwoch, 10. Juni 2009

PATH, noch übersichtlicher

Manchmal hat man einen so umfangreichen PATH, dass sogar die Darstellung der Einträge als einzelne Zeilen wie vor kurzem gezeigt noch nicht übersichtlich genug ist. Aber man kann mit Ruby ja sehr geschickt in der Liste suchen und nur das anzeigen, was interessant ist. Zum Beispiel so:

ruby -e "ENV['PATH'].split(';').each { |e| puts e if e =~ /mybin/i }"

So werde nur Pfadeinträge angezeigt, die den Text »mybin« enthalten (wobei die Groß-/Kleinschreibung nicht beachtet wird). Wieder muss das obige Kommando auf einer einzigen Zeile stehen, auch wenn es hier in zwei Zeilen dargestellt wird.

Dienstag, 9. Juni 2009

OpenOffice.org: Schnelles Versenden einer PDF

Eine sehr nützliche Funktion in OpenOffice.org finde ich das Versenden des Dokuments im PDF-Format. Die Funktion befindet sich hier:

Datei => Senden => E-Mail als PDF…

Damit wird eine temporäre PDF-Datei erzeugt (für die man noch Einstellungen vornehmen kann), dann wird eine E-Mail generiert und diese PDF gleich angehängt. Alles automatisch. Man muss dann bei der E-Mail nur noch den Empfänger angeben und gegebenenfalls ein paar warme Worte dazuschreiben. Und abschicken.

Montag, 8. Juni 2009

Nützliche Variablen in BAT-Dateien

Schreibt man BAT-Dateien unter Windows, so gibt es einige nützliche Variablen, die man benutzen kann:
  • %0: ergibt den Namen der BAT-Datei samt Pfad, mit dem sie aufgerufen wurde
  • %1: ergibt den ersten Kommandozeilenparameter
  • %2: ergibt den zweiten Kommandozeilenparameter (und so weiter)
  • %*: ergibt alle Kommandozeilenparameter
  • %~dp0: ergibt den absoluten Pfad zu dem Verzeichnis, in dem sich die BAT-Datei befindet (mit angehängtem \)
Die erste Option braucht vielleicht eine Erklärung. Steht die Datei test.bat im Verzeichnis C:\temp\test.bat und ist mein aktuelles Verzeichnis C:\temp, so könnte ich ja einfach test.bat eingeben, um die Datei aufzurufen. Dann würde %0 auch test.bat ergeben. Starte ich test.bat aber mit ..\temp\test.bat, so ist genau das auch der Text, den %0 liefert.

Samstag, 6. Juni 2009

jEdit und Speicherverbrauch

Wenn man jEdit unter Windows XP und Java 6 betreibt, kann es vorkommen, dass der Speicherverbrauch sprunghaft ansteigt, nachdem der Bildschirmschoner aktiv war. Ich vermute, dass die JVM durch den Bildschirmschoner gezwungen wird, den Fensterinhalt im eigenen Speicher zu puffern. Wenn der Schirm dann eine große Auflösung hat, kommt da schon was zusammen.

Um dieses Problem zu lösen, habe ich folgende Java-Option in das Kommando aufgenommen, das jEdit startet: -Dsun.java2d.noddraw=true

Das erhöht zwar den Speicherverbrauch von Anfang an, verhindert aber die extreme Steigerung durch den Bildschirmschoner, sodass insgesamt weniger Speicher verbraucht wird.

Freitag, 5. Juni 2009

Hexadezimalanzeige von Dateien

Ein weiteres Beispiel, wie sich Kurzskripte auf der Kommandozeile gewinnbringend einsetzen lassen: Wir wollen eine Datei hexadezimal anzeigen lassen. Ein möglicher Aufruf des Ruby-Interpreters zu diesem Zweck sieht so aus (unter Windows):

ruby -e "File.open('blah.zip', 'rb') { |f| f.each_byte { |b| printf '%02X ', b } }"

Hier wird die Datei blah.zip angezeigt.

Anmerkung: Auch wenn die Darstellung oben zwei Zeilen anzeigt, so gehört doch alles in eine Zeile.

Donnerstag, 4. Juni 2009

FPSpreadsheet aktualisiert

FPSpreadsheet ist eine wirklich nützliche Bibliothek für Free Pascal, wenn man vor der Aufgabe steht, einfache ODS- oder XLS-Dateien erzeugen zu müssen. Und das Beste ist: FPSpreadsheet wird aktiv weiterentwickelt! Vor knapp zwei Tagen gab es die letzte Aktualisierung (einige Ergänzungen für das Excel-5-Format waren das in dem Fall).

Hier gibt’s weitere Informationen: http://wiki.lazarus.freepascal.org/FPSpreadsheet

Mittwoch, 3. Juni 2009

Übersichtliche PATH-Anzeige unter Windows

In einer Windows-Kommandozeile ist die Anzeige der Umgebungsvariable PATH sehr unübersichtlich. Um hier mehr Durchblick reinzubringen, kann man den Umstand ausnutzen, dass man in vielen Skriptsprachen kleine Progrämmchen direkt über die Kommandozeile eingeben kann. Für Ruby sieht das zum Beispiel so aus:

ruby -e "puts ENV['PATH'].split(';')"

Dieses Skript holt sich den Inhalt der PATH-Variable und trennt ihn auf, mit dem Semikolon als Trennzeichen. Das resultierende Feld wird dann einfach ausgegeben, wobei jedes Element auf eine neue Zeile geschrieben wird (so arbeitet puts, wenn es ein Feld auszugeben hat). Es kommt also jedes Element der PATH-Variable auf eine eigene Zeile, was der Übersichtlichkeit sehr hilft.

Dienstag, 2. Juni 2009

Startschwierigkeiten, Teil 2

Rails 2.3.2 benutzt SQLite 3 als Standarddatenbank. Was man wissen muss: Die Ruby-Anbindung für SQLite 3 muss installiert sein, damit Rails eine Anfrage verarbeiten kann, selbst wenn die angesprochene Rails-Anwendung keine Datenbank nutzt.

Nun war auf meinem Ubuntu zwar SQLite 3 installiert, nicht aber die Ruby-Anbindung. Welches Paket war nun vonnöten? Es stellte sich heraus, dass dieses Paket gebraucht wurde: libsqlite3-ruby (kann per Synaptic installiert werden).

Montag, 1. Juni 2009

Startschwierigkeiten mit Rails auf Ubuntu

Vor kurzem habe ich auf meinem Ubuntu Jaunty Jackalope Rails installiert. Ich habe dabei den Weg über rubygems beschritten, also einfach ein

gem install rails

abgesetzt. Die Installation klappte auch vorzüglich, nur war hinterher das rails-Kommando nicht verfügbar (also nicht in den Suchpfad eingebunden). Ich habe dann ein bisschen gesucht und es dann in diesem Verzeichnis gefunden: /var/lib/gems/1.8/bin. Aus diesem Verzeichnis lässt es sich dann auch aufrufen.

Den entscheidenden Hinweis brachte dabei folgendes Kommando:

gem environment

Das zeigt nämlich unter anderem das Standardinstallationsverzeichnis für Gems an.