September 4, 2009 at 11:05 am · Filed under Javascript
Javascript allows naming and assigning functions at the same time like:
var vname = function fname() {}
The function name fname is available only inside the function as a local variable:
var vname = function fname(){
console.log(typeof vname); // function
console.log(typeof fname); // function
}
console.log(typeof vname); // function
console.log(typeof fname); // undefined
If we “redefine” this local variable inside of the function, we get a strange effect:
var vname = function fname(){
console.log(typeof vname); // function
console.log(typeof fname); // undefined !!!
var fname = 1;
console.log(typeof fname); // number
}
console.log(typeof vname); // function
console.log(typeof fname); // undefined
Obviously the interpreter sees the variable declaration var fname on entrance into the function and does not provide the function variable at all.
August 27, 2009 at 11:01 am · Filed under Note to self
find . -newerBt '10 minutes ago' -depth 1 -print 2>/dev/null
Juni 24, 2009 at 9:59 pm · Filed under Postgresql
Die im vorletzten Artikel vorgestellte Lösung hat den Nachteil, den ganzen Table my_table zu locken.
Das ist dann ein Problem, wenn criterion mittels unique constraint eindeutig gemacht wird und nach der Funktion eine zeitaufwendige Funktion (z.B. eine Suche) in derselben Transaktion folgt: Dann warten nämlich alle Prozesse, die ein findOrCreate machen wollen, unabhängig mit welchem Wert für criterion, auf den Abschluss der ersten Transaktion, da erst zu diesem Zeitpunkt sichergestellt werden kann, dass die Spalte wirklich unique ist.
Eigentlich sollte es aber möglich sein, dass parallele Transaktionen mit anderen Werten für criterion unbehelligt ausgeführt werden.
Mit dem folgenden, von Martin Heistermann und Stephan Lüderitz vorgeschlagenen Ansatz, umgeht man dieses Problem elegant:
CREATE OR REPLACE FUNCTION findOrCreate(
IN criterion_in text,
OUT record_id integer, OUT is_new bool) AS
$$
DECLARE
BEGIN
INSERT INTO
my_table (criterion)
VALUES
(criterion_in)
RETURNING id INTO record_id;
SELECT true INTO is_new;
EXCEPTION
WHEN unique_violation THEN
SELECT false, id into is_new, record_id FROM my_table
WHERE criterion=criterion_in;
END
$$ language plpgsql;
Wie in dieser Präsentation (PDF) beschrieben, läßt PostgreSQL das parallele Einfügen verschiedener Werte mittels findOrCreate zu, zwingt aber bei zwei Transaktionen, die denselben Wert einfügen wollen, die zweite, mit dem Insert auf das Ende der ersten zu warten.
Findet die (potentiell teure) Suche in der Transaktion nach findOrCreate statt, wird diese gar nicht mehr ausgeführt, da findOrCreate per Exception die von der ersten Transaktion neu eingefügte Zeile ermittelt und gleich mit deren Ergebnissen weitermachen kann.
Mai 19, 2009 at 9:57 pm · Filed under Allgemein
Kampagne gegen Terroristen in Deutschland. Sehr schön.
Mai 16, 2009 at 5:31 pm · Filed under Postgresql
Oft steht man vor dem Problem, einen Datensatz anhand eines Kriteriums zu finden bzw. ihn, falls nicht vorhanden, einzufügen. Bei derartigen Operationen ist es wichtig darauf zu achten, dass nicht mehrere Prozesse, die quasi gleichzeitig diesen Datensatz suchen, eine race condition hervorrufen.
Hier eine Lösung mittels stored procedure für postgresql. Dabei wird eine race condition zwischen Suche und Einfügen vermieden und nur minimales Locking gebraucht:
CREATE OR REPLACE FUNCTION findOrCreate(
IN criterion_in text,
OUT id int, OUT is_new bool) AS
$$
DECLARE
BEGIN
LOCK TABLE my_table;
SELECT false, id FROM my_table WHERE criterion=criterion_in INTO is_new, id;
IF id IS NULL THEN
INSERT INTO
my_table (criterion)
VALUES
(criterion_in)
RETURNING id INTO id;
SELECT true INTO is_new;
END IF;
RETURN;
END
$$ language plpgsql;
Man beachte die praktischen OUT-Parameter, die es ermöglichen, diese Funktion wie folgt aufzurufen:
SELECT id, is_new FROM findOrCreate(criterion);
Rückgabewerte sind id und is_new, die einem die Datenbank-Id angeben, und ob diese neu angelegt wurde.
Der Table-Lock wird beim Beenden der Funktion (die immer implizit eine Transaktion ist) automatisch beendet.
Mai 15, 2009 at 7:25 pm · Filed under PHP, Ruby
Laut PHP-Doku ist das Verhalten der Pseudo-Variablen $this wie folgt:
$this is a reference to the calling object (usually the object to which the method belongs, but can be another object, if the method is called statically from the context of a secondary object).
Schauen wir uns folgendes Beispiel an:
class A{
function __construct(){
$this->name = 'A';
}
function echoThisName(){
echo "My Name is {$this->name}.\n";
}
}
Jetzt rufen wir die Methode mal als Instanzmethode und mal statisch auf:
$a = new A();
$a->echoThisName();
A::echoThisName();
My Name is A.
PHP Fatal error: Using $this when not in object context in
/Users/aljoscha/test.php on line 9
Fatal error: Using $this when not in object context in
/Users/aljoscha/test.php on line 9
Das ist vernünftig. (ausser: Warum muss sich PHP eigentlich immer wiederholen? Ist eine Fehlermeldung zu subtil?)
Jetzt rufen wird diese Methoden aus einer anderen Klasse B heraus auf:
class B{
function __construct(){
$this->name = 'B';
}
function echoAsName(){
$a = new A();
$a->echoThisName();
A::echoThisName();
}
}
$b = new B();
$b->echoAsName();
Und das gibt:
My Name is A.
My Name is B.
Wir haben die Methode echoThisName der Klasse A statisch aufgerufen, aber $this ist darin trotzdem gesetzt, und zwar als wären wir in der Instanz $b der Klasse B.
$b hat sich die statische Methode gekapert.
Was sagt Ruby dazu?
class A
def initialize
@name = 'A';
end
def echoThisName
puts "My Name is #{@name}.\n";
end
end
$a = A.new;
$a.echoThisName;
A::echoThisName;
ergibt:
My Name is A.
test.rb:13: undefined method `echoThisName' for A:Class (NoMethodError)
Rufen wir A::echoThisName aus einer Instanz von B auf:
class B
def initialize
@name = 'B';
end
def echoAsName
$a = A.new;
$a.echoThisName;
A::echoThisName;
end
end
$b = B.new;
$b.echoAsName;
Ist das Ergebnis entsprechend:
My Name is A.
test.rb:23:in `echoAsName': undefined method `echoThisName'
for A:Class (NoMethodError) from test.rb:28
Besser.
Dank an Stephan für den Hinweis auf die Dokumentation des Verhaltens in PHP.
Januar 15, 2009 at 2:27 pm · Filed under PHP
Manche Dinge in PHP sind so komisch, dass man sie sich am besten einmal notiert, um sich dann in Ruhe darüber zu wundern.
Falls z.B. in PHP eine Variable $a auf den Wert null gesetzt ist, liefert isset($a) trotzdem false. (Das ist nichts Neues, aber es ist merkwürdig im Wortsinne.) Interessant auch das Verhalten von empty und is_null für ungesetzte Variablen und Variablen mit dem Wert null. Dazu initialisieren wir Variable $a mit dem Wert null und lassen Variable $b völlig uninitialisiert:
$a = null;
# $b wird nicht initialisiert
Hier nun die Tests:
| Test |
$a |
$b |
| isset() |
false |
false |
| empty() |
true |
true |
| is_null() |
true |
true |
| === null |
true |
true |
Das Ergebnis von isset($a) ist zumindest gegen jede Intuition.
Bizarr wird es aber bei der gedoppelten (?) Notice PHP Notice: Undefined variable: b in /home/aljoscha/test.php on line 10
Notice: Undefined variable: b in /home/aljoscha/test.php on line 10, die durch is_null($b) bzw. ($b === null) ausgelöst wird, und dem überraschenden Ergebnis: true!
Februar 9, 2008 at 4:43 pm · Filed under Mootools, Prototype
In what they call a “backwards compatibility change” the prototype core developers have introduced some changes to the prototype Hash class.
A little history:
From version 1.5 the Hash class started behaving a bit differently because now the Enumerable methods where copied into the Hash prototype instead of into the instances, as before. That helped minimize the memory footprint but introduced incompatibilities and removed the possibility to patch Enumerables methods because after patching Enumerable one would have to manually copy its methods into all “inheriting” classes again.
To my understanding that is in conflict with the dynamic inheritance in prototype-based languages like javascript.
See this thread for more info.
Now with 1.6. things get worse. The Hash object is not an JS object with added functionality anymore, its a wrapper around one.
The following code will work in 1.5.0.2 but not in 1.6:
test = $H({a: 1, b:2});
alert(test.a); // -> 1 in version 1.5
Instead, in prototype 1.6 you have to write test.get('a') to get to the property “a” of the underlying object. In case you need the whole object, there is always test.toObject() to the rescue. Bye bye, consise and short notation.
I feel the developers forgot what made prototype so wildly successfull: Its beautiful concept of enhancing the built in objects, not wrapping them.
I consider leaving the prototype world alltogether and will switch to mootools.
Unlike prototype, mootools returns a hash on filtering a hash.
November 25, 2007 at 12:07 am · Filed under MacOSX
After installing Leopard, the previous Apache configuration file in /etc/httpd/httpd.conf is no longer used. The Apache configuration sits in /etc/apache2/httpd.conf now.
In order to enable PHP again, I uncommented the following line first:
LoadModule php5_module libexec/apache2/libphp5.so
Second, to get my virtual hosts running again, I used the adapted Leopard version of Patrick Gibsons excellent utility
virtualhost.sh which even automatically moves all prior (Tiger) virtual hosts.
Finally to get rid of the error
Can't connect to local MySQL server through socket '/var/mysql/'
I successfully followed the steps found here:
sudo mkdir /var/mysql/
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock
Everything is up and running fine now.
« Previous entries ·
Next entries »