Re: [PHP-DEV] "::" meaning and documentation From: Kristian Köhntopp (kk <email protected>)
Date: 07/04/00

Ulf Wendel wrote:
> what's the meaning of "::"? I was surprised to see that this code works:

How it _should_ work, if PHP was to behave similarly to
other OO languages:

Uses of :: in an instance
=========================

Using :: on instance functions
------------------------------

If used in an instance of a class, :: should be able
to address a shadowed method in a superclass of the
current instances class. That is,

class a {
  function somef() {
   print "I am somef() in a\n";
  }
}

class b extends a {
  function somef() {
    print "I am somef() in b\n";
  }

  function otherf() {
    $this->somef(); // will print "I am somef in b"
    a::somef(); // will print "I am somef in a"
  }
}

$b_instance = new b;
$b_instance->somef(); // will print "I am somef in b"

This is useful to address a shadowed instance method
in a superclass of a class, for example when extending
an initalizing function. Note how the name of the
superclass is mentioned multiple times in b, which is
a denormalization. Changing the name of a classes superclass
will make changed in many code locations necessary.

It would be much more elegant if you had a pseudo variable
$super instead which could be used to reference a classes
superclass as in

class b extends a {
  function somef() {
    print "I am somef() in b\n";
  }

  function otherf() {
    $this->somef(); // will print "I am somef in b"
    $super->somef(); // will print "I am somef in a"
  }
}

Alternatively, it would be useful if the class and
function names around a T_PAAMAYIM_NEKUDOTAYIM need
not be T_STRING, but can be variable references,
facilitating syntax like

class b extends a {
  function somef() {
    print "I am somef() in b\n";
  }

  function otherf() {
    $c = get_parent_class(); // returns (string) "a"

    $this->somef(); // will print "I am somef in b"
    $c::somef(); // will print "I am somef in a"
  }
}

Using :: on instance variables
------------------------------

This could be used to address shadowed instance variables
as well, but the concept of "shadowed instance variable"
is only useful when you consider static initalizers of
instance variables. That is, consider

class a {
  var $some_var = "initializer in a";
}

class b extends a {
  var $some_var = "initializer in b";

  function showvar() {
    print $this->some_var; // will print "initializer in b"
    print a::some_var; // will print "initializer in a"
  }
}

That would be sensible, but if it doesn't work that way,
it is of little importance.

Uses of :: outside of an instance
=================================

Class functions
---------------

Outside of an instance, :: does make sense only to address
(Objective C name:) class functions alias (Java name:)
static class member functions and (Objective C name:)
class variables alias (Java name:) static class member variables.

A class function/static class member function is a function
which can be called in a class even when no instance of
that class is available. Such functions are useful for a
variety of purposes (see any Objective C runtime documentation
or any Java handbook), but they can be emulated with plain
functions (raising namespace issues).

Example use:

class a {
  function sfunction() {
    print "I am sfunction in a\n";
  }
}

a::sfunction(); // will print "I am sfunction in a"

A class function should be able to call other class functions,
but cannot call instance functions and therefore not refer to
$this, as there is no instance. It is of little use to create
a default instance (of a default class), raising an error
condition would be more sensible.

Class variables
---------------

A class may have class variables. Such variables are useful to
keep track of all instances of a class, for example a database
class keeping track of all database links in all database class
instance objects, or for example a Drawable class, keeping track
of all Drawable instances and providing a draw_all() class
function.

This can be emulated using a Keeper class with a single
instance and putting all instances into the Keeper after creation,
but having it in a class would still be useful in some cases.

class a {
  var $class_var;
}

a::class_var = 10;

Assorted problems
=================

:: outside of classes introduces problems with variable interpolation,
as the construct is no longer introduced by $ signs. This leads at least
to strange syntax and may be creating other, more serious problems as
well.

In Smalltalk and in Objective C, classes are objects, too. Their
class is named "Metaclass" and Metaclass implements a number of
standard functions for dealing with Classes. An instance of
Metaclass is a class, and belongs to the class Metaclass as well,
terminating this recursion.

That is, in Objective C and Smalltalk

  $o = new SomeClass; // $c is an instance of the class SomeClass
  print $o->get_class_name(); // will print SomeClass

  $c = $o->get_class(); // does not return a string, but an object
                        // which is the class SomeClass.
  print $c->get_class_name(); // will print MetaClass

  $m = $c->get_class(); // does return the class object for $c,
                        // which is the MetaClass object
  $m->get_class(); // will print MetaClass, also.

Somehow a similar Semantic should be defined for PHP4 as well. It
need not be identical, but it should be defined to clear things up.
And it should be defined in a way that makes things function in
a sensible way (not just "because the implementation happens to be
this way").

Kristian

-- 
Kristian Köhntopp, NetUSE AG Siemenswall, D-24107 Kiel
Tel: +49 431 386 436 00, Fax: +49 431 386 435 99
Using PHP3? See our web development library at http://phplib.netuse.de/

-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, e-mail: php-dev-unsubscribe <email protected> For additional commands, e-mail: php-dev-help <email protected> To contact the list administrators, e-mail: php-list-admin <email protected>