One of the things that has been confusing with the introduction of static members is the difference between marking a member as static at “compile-time” in the static constructor (public static a = 1) and accessing the static scope at “runtime” in the instance (static.a = 1). This can be very confusing, especially to the uninitiated.
My proposal then is to rework the static scope as follows. The current “static” scope is renamed to “self” and is bound to the declaring class. Second, a static scope is added that provides “late static binding”. Both scopes should use the scope-resolution operator to access/update members.
// A.lucee
class {
static {
private a = 1;
private b = 2;
private c = 10;
public function getSelfA() {
// these should error
return this.a; // "this" only available to instances
return static.a; // invalid use of static scope - requires double-colon
return self.a; // invalid use of self scope - requires double-colon
// these should work
return a;
return self::a;
}
public function getStaticB() {
// late-static binding static scope introduced.
return static::b;
}
}
// access static scope from implicit instance constructor...
self::a = 7;
}
// B.lucee
class extends A{
static {
private a = 3;
private b = 4;
public function getC() {
return self::c; // error - no member c found
return static::c; // error - no member c found
}
}
}
// index.lucee
echo(A::getSelfA()); // 1
echo(B::getSelfA()); // 1
echo(A::getStaticB()); // 2
echo(B::getStaticB()); // 4
new A();
echo(A::getStaticA()); // 7