--disable-experimental-aggregate and
--disable-experimental-overload?
Just in case we really want to make it optional and have new way
for overloading/multiple inheritance.
We can document these features as EXPETIMENTAL as long as we want,
right?
--
Yasuo Ohgaki
Kristian Koehntopp wrote:
> I have several observations regarding the newly implemented
> aggregate() und overload() extensions. Depending on the
> correctness of these observations you may want to reconsider the
> inclusion of these extensions in the current build of PHP.
>
> The following has not in its entirety verified in the source and
> may be incorrect or incomplete. Please correct me.
>
> Situation:
>
> $obj = new Origclass; aggregate($obj, "Classname"); is a
> function which adds all instance variables and methods from
> class Classname to an object $obj of an original class
> Origclass. There are variations of aggregate which allow you to
> add instance variables and methods selectively by enumeration
> and regex.
>
> Observation:
>
> aggreate and friends break the introspection in PHP, and may
> interfere with serialization and sessions. This is, because
> get_class($obj) returns Origclass, and no trace of Classname.
> Also, $obj is_a() Origclass, but not is_a(Classname), leading to
> serialization of $obj as a pure Origclass, and reinstantiation
> as a pure Origclass with no methods from Classname at all.
>
> This is the situation of serialize() in PHP 3 at a slightly
> elevated level. Reminder: In PHP 3, serialize() did not record
> the class of an object on serialization, and unserialize()
> consequently produced an object with no methods at all, which is
> in fact quite useless.
>
> Also, because of the fine grained nature of the more advanced
> variations of aggregate, there is no fast way to describe the
> class or type of an object instance. The only way to completely
> describe an object is to completely enumerate its instance
> variables and instance methods. Essentially, get_class and
> friends become meaningless.
>
> Alternative:
>
> aggregate is a badly designed way to introduce multiple
> inheritance like functionality. There are at least two tested
> ways to implement MI functionality. Statically typed languages
> such as C++ set type == class and implement pure MI. Regarding
> PHP, this would lead to
>
> class C extends A, B { ... }
>
> with the order of A and B being important. Also,
> get_parent_class() would need to be modified to return
> inheritance level information or inheritance graph information
> together with class names in order to produce meaningful
> information. Something like
>
> $v = get_parent_class($complicated_object);
>
> $v would be
>
> array("A" => "B", "B" => "C", "B" => "D");
>
> for
>
> class A extends B ...
>
> class B extends C, D ...
>
> An alternative, possibly cleaner way would be the introduction
> of interfaces and categories. In this scenario we keep single
> inheritance. We introduce declarations of interfaces, which may
> contain a number of instance variables and functions. Interfaces
> are a simple declaration of these, there is no implementation at
> all in an interface.
>
> A class may claim conformity with an interface. This means that
> the class at least has all the instance variables the interface
> demands and has at least implementations for all member
> functions of the interface. The class may implement all this
> independently or it may import a category.
>
> A category is class-subset, and always an implementation of an
> interface (you cannot define a category for which no interface
> definition is being known).
>
> Interfaces and Categories are found in some dynamically typed
> languages, sometimes under slightly different names. They
> separate type and class, and in order for them to function in
> PHP we would need enumerative functions and predicates to
> complement the new language constructs (get_defined_interfaces(),
> get_defined_categories(), conforms_to($interface_name)).
>
> Recommendation:
>
> As-is aggregate() is a broken design, and will break existing
> older functionality. It will create a number of support issues,
> and later backward compatibility issues. It may inspire even
> more broken "fixes" for these issues, effectively uglifying the
> language itself or at least its object system.
>
> The best would be to remove aggregate() completely, and bury it.
> It should be replaced by a proper MI system, probably one for a
> dynamically typed language, as PHP is such a language.
>
> If aggregate() functionality is being used right now, and is
> critical, it should be kept, properly documented, the drawbacks
> spelled out in all its ugliness and its use strongly
> discouraged. It should be clearly marked as obsolete from day 1,
> and may be removed at any time. If someone uses this feature
> despite the warning labels, this person deserves everything that
> happens.
>
>
>
> Situation:
>
> The overload() extension allows userland code to intercept get,
> set and call operations on the instance variables and instance
> functions of an object. It does this by defining the special
> fixed name functions __get, __set and __call in a class, which
> are enabled by calling overload() on this class.
>
> It also allows, according to Sebastian Bergmann, and in spite of
> the current documentation at
> http://www.php.net/ref.overload.php, __get_x(), __set_y() and
> __call_x() functions in order to intercept accesses and calls to
> instance variable x and method y respectively.
>
> I haven't verified this in source, but Sebastian claims it
> works.
>
> Observation:
>
> If this is NOT the case, I have no issue with overload(). It is
> dangoerous, but it is an expert feature and the design is okay.
>
> If overload() allows for __get_x(), though, this is bad design.
> The reason for this is that we get namespace pollution and,
> again (*), automatically called callback functions with a
> variable name. There will interoperate badly with inheritance,
> with dynamically created, undeclared instance variables and with
> aggregate().
>
> Recommendation:
>
> If overload() indeed supports variably named callback functions
> such as __get_x(), support for this should be removed in order
> to avoid a number of possible inconsistencies and namespace
> pollution.
>
>
> End Rant, fire away...
>
> Kristian
>
> (*) We had them with PHP 3 constructor names, which were an
> extremely bad idea in the first place.
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php