Kategorien
Diplomarbeit

Eclipse, Subversion und Spket

Die drei Sachen verwende ich gerade. Da aber irgendwie gerade was abschmiert, steige ich mal auf „unstable“ (aka 3.5M3)um:

http://download.eclipse.org/eclipse/downloads/

Eclipse Update URLs:

Kategorien
Diplomarbeit

public, private und „privileged“ in Javascript

Jetzt wirds hässlich. Natürlich gibts „public“ und „private“ auch in Javascript. Allerdings, wie immer, ein bisschen anders:
Public

function Constructor(value) {
    this.membername = value;
}
Constructor.prototype.membername = value;

myConst = new Constructor("foobar");
print myConst.membername; // prints 'foobar'

Private

function Constructor(value) {
    var self = this;
    this.membername1 = value; // public member
    var membername2 = value + "private"; // private member
    function membername() { // private method
        print self.member; //access to public member in private method
        print membername2; // access to private member in private method
    }
}

myConst = new Constructor("foobar");
print myConst.membername1; // prints 'foobar'
print myConst.membername2; // prints 'undefined'
myConst.membername(); //no such function

Wenn man jetzt aber z.B. mittels dem property „prototype“ auf private-members zugreifen will, dann wird man scheitern. „public“ hat keinen Zugriff auf „private“. Dazu muss man die „privileged“-Methoden verwenden.

Privileged

function Constructor(value) {
    this.membername = function membername() {
        print "hi";
    };
}

myConst = new Constructor("foobar");
myConst.membername(); // prints "hi"
Kategorien
Diplomarbeit Sonstiges

Javascript-Klassen und Objekte

Habe gerade noch das hier gefunden: Class-Based vs. Prototype-Based Languages

Ich hab zwar schon hier auf einen schönen Artikel verwiesen, aber jetzt nochmal das ganze aus meinem Munde.

Javascript is Objektorientiert. Schon immer. Glaub ich. 1995 das erstmal mit Netscape veröffentlicht, sind wir inzwischen bei Javascript 1.8 angekommen (seit 18. Dezember 2007). Javascript wird übrigens von Mozilla „gemanaged“. Und Javascript ist nicht Ecmascript. Vielmehr ist Javascript ein Dialekt von Ecmascript.

Soviel dazu. Javascript implementiert ECMAScript, genauer ECMA-262, edition 3. Innerhalb davon gibt es keine „Klassen“ im eigentlichen Sinne. Viel eher werden direkt Objekte geboren.

function meinObjekt () {
    this.zahl = 1;
}

Und schon haben wir ein Objekt/Klasse mit dem Namen „meinObjekt“. Und eine Eigenschaft „zahl“ hat es auch.

var objekt = new meinObjekt();
window.alert(objekt.zahl);

Und somit kriegen wir ein Fenster mit einer „1“ drinnen. Es gibt auch private und öffentliche Eigenschaften/Methoden, allerdings ist Javascript da etwas bockig:

function meinObjekt () {
     var self = this;
 
    /** @private */
    var foobar = "private";
    var privateMethod = function () {
        window.alert(foobar  + " " + self.barfoo);
    };
 
    /** @public */
    this.barfoo = "public";
    this.public_method = function () {
        window.alert(foobar + " " + this.barfoo);
        private_method();
    };
}

Wer sich wundert was das „self“ soll, das liegt an Javascript. Während der Zugriff von öffentlichen auf private Methoden prima klappt, ist der Zugriff von privaten auf öffentliche Methoden … anders :). Hierzu wird einfach „this“ in „self“ kopiert und dann kann wie „this“ verwendet werden. Jippie.

Ich verwende den Spass gerade so:

var logger = function() {
};
logger.prototype = {
	log : function(msg) {
		console.log(this.getNow() + msg);
	},
	getNow : function() {
		return new Date();
	}
};
var foobar = new logger();
logger.log("foobar"); // prints "foobar"

Man spricht hier von „prototyp-basierter“ Objektorientierung. Interessant wirds in dem „neuen“ Standard ECMA-262, edition 4. Dort gibt es dann tatsächlich auch Klassen:

class C {
	var val // a variable property
	var large = Infinity // a variable property
	const x = 3.14 // a constant property
	function f(n) { return n+val*2 } // a method property
}

Da ja Javascript schön dynamisch ist, gibt es auch dynamische Klassen:

dynamic class C {
}
c = new C
c.x = 37 // adds a property
delete c.x // removes it again

Weiter gehts mit Vererbung, jetzt mit Schlüsselwörtern wie „extends“:

class C {
	var val
	function f(n) { return n+1 }
}
class BetterC extends C {
	var large = 123456 // new value property
	override function f(n) { return n*3 } // overridden method property
}

Es gibt auch „final“ als Schlüsselwort, eine so bezeichnete Klasse kann dann keine Kinder kriegen. Und zu guter Letzt werden auch Interfaces eingeführt. Somit wird Ecmascript und somit auch Javascript an die „normale“ Objektorientierung herangeführt. Die komplette Spezifikation des „neuen“ ECMAScripts findet sich unter:

http://www.ecmascript.org/es4/spec/overview.pdf

Kategorien
Diplomarbeit

Javadoc für Javascript

http://www.jsdoctoolkit.org/

Erster Eindruck: Exzellent.

Kategorien
Diplomarbeit

Test und so

hab heute mein eigenes Unit-Test-Dings geschrieben. Kann nix, bin aber stolz wie Oskar 🙂

Kategorien
Diplomarbeit

Javascript aus FF-Erweiterung in der Webseite benutzen

Langer Titel, kurzer Blogeintrag. Ich bastel gerade daran rum, diverse Javascript-Funktionen innerhalb der HTML-Seite zu benutzen. Das kann ziemlich hässlich werden:

var head = this.getContentDocument().getElementsByTagName("head")[0];
var script = this.getContentDocument().createElement("script");
var showImage = this.getContentDocument().createTextNode("function showImage(id) { "
		 + "var image = document.getElementById(id);"
		 + "image.style.display = \"inline\"; "
		 + "image.parentNode.previousSibling.addEventListener(\"mouseout\",
		 function() {"
		 + "window.setTimeout(fadeImage, 1500, id);"
		 + "}, false)"
		 + "}");
script.appendChild(showImage);
head.appendChild(script);

Alles doppelt escapen und so. Kein Spass. Hässlich zum Lesen. Lösung:

var head = this.getContentDocument().getElementsByTagName("head")[0];
var script = this.getContentDocument().createElement("script");
script.setAttribute("src", "resource://jslibs/foobar.js");
script.setAttribute("type", "text/javascript");
head.appendChild(script);

Nix spektakuläres, aber innerhalb der Datei „foobar.js“ kann man jetzt ‚ganz normales‘ Javascript schreiben. Ich freu mich über sowas 😉

Kategorien
Diplomarbeit Sonstiges

Registry Pattern in Javascript

Wer globale Objekte vermeiden will, aber trotzdem globalen Zugriff will (z.B. auf eine Datenbankinstanz) baut sich eine Registry. Im Prinzip nur das Singleton-Pattern mit get und set-Methoden:

registry = (function() {
	// private attributes
	var blubb = new Array();
	// private methods
	var getIndex = function(_name) {
		for (var i = 0; i < blubb.length; i++) {
			if (blubb[i].name == _name) {
				return i;
			}
		}
		return null;
	};

	return {
		// public attributes

		// public methods
		setValue : function(_name, _value) {
			var foo = this.getValue(_name);
			if (foo == null) {
				var temp = new Object();
				temp.name = _name;
				temp.value = _value;
				blubb.push(temp);
			} else {
				blubb[getIndex(_name)].value = _value;
			}
		},
		getValue : function(_name) {
			for (var i = 0; i < blubb.length; i++) {
				if (blubb[i].name == _name) {
					return blubb[i].value;
				}
			}
			return null;
		}
	}
})();
// registry is already available
registry.setValue("foo", "bar");
registry.getValue("foo"); // gives "bar"
registry.getValue("bar"); // gives null
[/sourcecode]

Siehe auch: http://yuiblog.com/blog/2007/06/12/module-pattern/

Kategorien
Diplomarbeit Spass

Wie man das Laden einer Seite abfängt …

Ohne Witz. Seit 4 Wochen doktor ich daran rum und ENDLICH hab ich den richtigen (bzw. funktionellen) Weg gefunden wie man es macht:
overlay.xul:

<overlay id="extensionId" 
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script type="application/x-javascript" src="chrome://extensionId/content/myJs.js"/>
</overlay>
</pre>
<strong>myJs.js:</strong>
<pre lang="javascript">
Components.utils.import("resource://jslibs/test.js");
function startupWrapper() {
	var appcontent = document.getElementById("appcontent"); // browser
	if (appcontent) {
		appcontent.addEventListener("DOMContentLoaded", function() {
					justATest(getBrowser());
				}, true);
	}
}

test.js:

var EXPORTED_SYMBOLS = ["justATest"];
justATest = function(gBrowser) {
	var body = gBrowser.mCurrentBrowser.contentDocument.getElementsByTagName('body')[0];
}

Herzlichen Glückwunsch. Vorher hab ich „nur“ auf DOMContentLoaded gehört, das hat mir dann aber beschert, dass meine Funktion pro XUL-Dokument aufgerufen wurde, also z.B. für die Web Developer Toolbar, die Locationbar, den Browser an sich und dann erst die Webseite. Vorher hab ich das kläglich mit

if (gBrowser.mCurrentBrowser.contentDocument.documentURI != "about:blank") {
  // do something
}

abbeholfen, aber das ist ja doof 🙂 Jetzt gehts. Hooray

Kategorien
Diplomarbeit Sonstiges

Javascript-Objekte

Guter Artikel über Objekte in Javascript. Eher nur Grundsätzliches, trotzdem lesenswert: JavaScript’s class-less objects im JavaRanch Journal.

Kategorien
Diplomarbeit

xUnit

Testen von Programmen ist wichtig. Das wurde schon recht früh erkannt. Ich hab ja schon früher über Unit-Testing und Refactoring geschrieben. Jetzt les ich gerade das Buch „xUnit Test Patterns – Refactoring test code“ von Gerard Meszaros (ISBN-13: 978-0-13-149505-0). Dicker Schmöker mit knapp 890 Seiten. Ich werde hier jetzt ab und an ein paar Gedanken zu diesem Buch verfassen und wahrscheinlich auch Kapitelweise eine Zusammenfassung. Eigentlich dient das nur meinem Verständnis, aber vielleicht hat auch jemand anderes was davon 🙂

The Fragile Test Problem

In meinem Praxissemester bin ich über WinRunner gestolpert. An sich eine schöne Idee, einfach ein paar Mausbewegungen und Klicks aufzeichnen und schauen ob auch das rauskommt, was rauskommen sollte. Scheitert aber schon an diversen Sachen, z.B. wenn man die Sprache im Programm umstellt. Zwar sollte sowas nicht die Funktionalität eines Programmes verändern, aber wer weiss, Bugs sind überall. Meszaros kategorisiert das ganze (er nennt es „The Fragile Test Problem“) in vier Fallgruben aufgeteilt.

Behaviour Sensitivity

Wenn sich das Verhalten eines Systems ändert (weil sich z.b. die Anforderungen geändert haben), dann ist die Wahrscheinlichkeit, dass die Tests, die die geänderte Funktionalität prüfen, scheitern sehr gross (uff, was ein Satzbau). Das ist jetzt nichts spezielles für so Programme wie WinRunner, das ist immer so. Wenn ich bei einem Auto auf vier Reifen teste, die Requirements aber plötzlich ein Dreirad wollen, dann MUSS das schiefgehen. Richtig fies wird es erst, wenn wir uns auf die Funktionalität verlassen um das System in einen Status zu bringen, in dem wir einen Test ausführen.

Interface Sensitivity

Grundsätzlich ist das Testen einen Systems über die Benutzeroberfläche eine schlechte Idee. Jede minimale Änderung bringt jeden Test zum Scheitern. Und dies ist völlig unabhängig von der Benutzeroberfläche (GUIs wie QT oder GTK, CLI (Command Line Interfaces) oder Weboberflächen (Buzzword: Ajax, Web 2.0)).

Data Sensitivity

Alle Tests starten an einem Zeitpunkt, an dem bestimmte Konditionen gegeben sind. Irgendwelche Datenstrukturen sind vorhanden und werden genutzt. Solange man nich immensen Aufwand investiert um die Tests von diesen Daten unabhängig zu machen, ist es höchstwahrscheinlich das die Tests scheitern.

Context Sensitivity

Nachdem der Datenkontext schon wichtig ist, kommen natürlich noch andere externe EInflüsse dazu. Das können so simple Dinge wie die Uhrzeit sein (Sommer-/Winterzeitumstellung), aber auch Geräte wie Drucker oder Server.

All diese Abhängigkeiten machen das deterministische Wiederholen von Tests sehr, sehr schwierig. Natürlich gibt es viele Möglichkeiten diese Abhängigkeiten zu umgehen, aber egal welche Methode man nimmt, sie bleiben bestehen. Die xUnit-Familie stellt ein paar Muster zur Verfügung die uns einen grossen Grad an Kontrolle ermöglichen. Wir müssen nur noch lernen sie zu nutzen.

Dieses Testen wird übrigens „regression testing“ genannt. Regression bedeutet auf Deutsch „Rückwärtsbewegung“ und spiegelt das auch gut wieder. Wir haben ein fertiges Produkt und bewegen uns beim Testen von Vorne nach Hinten (Von der GUI zum Backend). Einen völlig anderen Ansatz spielt hier die testgetriebene Entwicklung (test-driven development), die das Prinzip umkehrt. Mittels dieser Methode wird eher das Verhalten von Software die noch geschrieben wird beschrieben, als die fertige Software rückwärts getestet.