Perhaps a new concept in class-based OO programming, I'm not sure.
Depending on your perspective you could call it ancestor overloading (or
upstream overloading) or class underloading.
We are increasingly developing with the aid of frameworks & libraries. In
fact, this idea came from my current project using the Zend Framework.
These libraries, while greatly extensible, are also fairly self-extending.
That is, they include many classes that extend many classes, which is
great.
As consumers of these libraries, we can extend the classes and consume the
API however we please, but there is one sticking point.
We cannot change classes that many other classes extend without extending
or changing each child class and then making sure that our code uses the
new class.
For a concrete example, I was working with the Zend_Form_Element
subclasses, and I realized that I wanted to change some of the default
behavior (in Zend_Form_Element).
- at this point I will assume the reader understands why I wouldn't want
to just start changing the Zend library files -
There are many subclasses of Zend_Form_Element. If you want to change the
default behavior for all of them, you have 3 choices currently:
- Directly edit the Zend_Form_Element file in the library, -bad for
updates & other projects that use the library - subclass Zend_Form_Element and change declaration of the descendants to
extend new class - same problems - extend each child class and implement those subclasses in your app code
-very tedious and TONS of repeated code, breaks consistency of API for
developers.
There could be a better way, if we could insert a class into the family
tree.
And that's the heart of this idea, so I'll repeat it:
- insert a class into the family tree *
Image we do it using an alternative keyword to "extends", such as
"overloads".
Example:
class Library_Class { }
class Library_Subclass extends Library_Class {}
and then:
class My_LibClass_Overload overloads Library_Class{}
Now new instances of Library_Subclass actually extend
My_LibClass_Overload, which "extends" Library_Class. The developer would
then code My_LibClass_Overload as if it were declared like this:
class Library_Class {}
class My_LibClass_Overload extends Library_Class {}
class Library_Subclass extends My_LibClass_Overload {}
But indeed the declaration of Library_Subclass would not have to change.
This way developers could "extend" default functionality and have
existing library classes pick up the new functionality without
redeclaring anything in the library.
Downstream classes would still override any methods that they redeclare.
If you wanted to have end-point classes in the library have different
behavior, you would overload them instead, such as
class My_LibSubclass_Overload overloads Lib_Subclass {}
The benefit is that the application code can still consume "standard"
classes, such as Library_Subclass and not need to know or care about the
extended functionality.
Going back to my concrete example, my code could then still use
Zend_Form_Element_Text, but benefit from the modifications I added,
without me having to touch the library code.
I hope I've explained clearly what this could look like. I'm a younger
developer, so forgive me if I'm rough on the terminology -perhaps
overload/underload is not the best word for this functionality. Also, I'm
not sure if there are other class-based OO languages that allow this kind
of behavior... Prototypal languages perhaps, as is the case with
javascript and the Obj.prototype which (combined with anonymous functions)
allows you to extend the "base" functionality of other objects that
"extend" it.
Thank you for your comments and thoughts!
Chris Trahey
Web Applications Developer
Database Administrator
CSISD [Technology]
Sorry for duplicate message- mail server fail.
Chris Trahey
Web Applications Developer
Database Administrator
College Station I.S.D.
Perhaps a new concept in class-based OO programming, I'm not sure.
Depending on your perspective you could call it ancestor overloading
(or
upstream overloading) or class underloading.We are increasingly developing with the aid of frameworks &
libraries. In
fact, this idea came from my current project using the Zend Framework.
These libraries, while greatly extensible, are also fairly self-
extending.
That is, they include many classes that extend many classes, which is
great.
As consumers of these libraries, we can extend the classes and
consume the
API however we please, but there is one sticking point.
We cannot change classes that many other classes extend without
extending
or changing each child class and then making sure that our code uses
the
new class.For a concrete example, I was working with the Zend_Form_Element
subclasses, and I realized that I wanted to change some of the default
behavior (in Zend_Form_Element).
- at this point I will assume the reader understands why I wouldn't
want
to just start changing the Zend library files -
There are many subclasses of Zend_Form_Element. If you want to
change the
default behavior for all of them, you have 3 choices currently:
- Directly edit the Zend_Form_Element file in the library, -bad for
updates & other projects that use the library- subclass Zend_Form_Element and change declaration of the
descendants to
extend new class - same problems- extend each child class and implement those subclasses in your
app code
-very tedious and TONS of repeated code, breaks consistency of API for
developers.There could be a better way, if we could insert a class into the
family
tree.
And that's the heart of this idea, so I'll repeat it:
- insert a class into the family tree *
Image we do it using an alternative keyword to "extends", such as
"overloads".Example:
class Library_Class { }
class Library_Subclass extends Library_Class {}
and then:
class My_LibClass_Overload overloads Library_Class{}Now new instances of Library_Subclass actually extend
My_LibClass_Overload, which "extends" Library_Class. The developer
would
then code My_LibClass_Overload as if it were declared like this:
class Library_Class {}
class My_LibClass_Overload extends Library_Class {}
class Library_Subclass extends My_LibClass_Overload {}But indeed the declaration of Library_Subclass would not have to
change.This way developers could "extend" default functionality and have
existing library classes pick up the new functionality without
redeclaring anything in the library.
Downstream classes would still override any methods that they
redeclare.
If you wanted to have end-point classes in the library have different
behavior, you would overload them instead, such as
class My_LibSubclass_Overload overloads Lib_Subclass {}The benefit is that the application code can still consume "standard"
classes, such as Library_Subclass and not need to know or care about
the
extended functionality.Going back to my concrete example, my code could then still use
Zend_Form_Element_Text, but benefit from the modifications I added,
without me having to touch the library code.I hope I've explained clearly what this could look like. I'm a younger
developer, so forgive me if I'm rough on the terminology -perhaps
overload/underload is not the best word for this functionality.
Also, I'm
not sure if there are other class-based OO languages that allow this
kind
of behavior... Prototypal languages perhaps, as is the case with
javascript and the Obj.prototype which (combined with anonymous
functions)
allows you to extend the "base" functionality of other objects that
"extend" it.Thank you for your comments and thoughts!
Chris Trahey
Web Applications Developer
Database Administrator
CSISD [Technology]
Hi:
Perhaps a new concept in class-based OO programming, I'm not sure.
Depending on your perspective you could call it ancestor overloading (or
upstream overloading) or class underloading.
Haven't read the term in this thread yet, so I felt obliged to mention it:
what you want is called monkey patching[1]. Even so you present here a restricted 'language'-ified version of it, the general concept is still a fully reflective language.
Gwynne already referred to Runkit, which gives you all the tools you need.
However, since monkey-patching isn't something generally appreciate, I wouldn't go with promoting it to the language level. Instead, some Runkit functionality could be OO-ified and integrated into the Reflection API (somewhere along the lines of [2] perhaps).
A technical issue with your proposal you do not address are conflicts.
What happens when two classes overload the same class?
Beside that, the best thing you could to for the moment is to convince the Zend framework guys to read up about Open Implementations[3].
Best regards
Stefan
[1] http://gbracha.blogspot.com/2008/03/monkey-patching.html
[2] http://instantsvc.svn.sourceforge.net/viewvc/instantsvc/branches/metaprogramming/src/MetaPHP/Reflection2/class.php?revision=1076&view=markup
[3] Gregor Kiczales, "Beyond the Black Box: Open Implementation," IEEE Software, vol. 13, no. 1, pp. 8-11, Jan. 1996, doi:10.1109/52.476280
--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax: +32 2 629 3525
Hi,
The feature specified by Chris remind me the "metaclass" extension system of
Groovy language (I am not a Groovy Expert, but properties seems similar).
+1 for this kind of feature at a language level, IMHO it will really help
for Aspect Oriented Programming, Legacy Code Refactoring, Unit Testing
(Mocking mecanism).
Gwynne already referred to Runkit, which gives you all the tools you need.
IMHO Language-level features are much more appreciated in facts, and
Professionals pratices-required features (AOP, unit-test...) should be
language-level (in order for pratices to become more popular)
However, since monkey-patching isn't something generally appreciate, I
wouldn't go with promoting it to the language level. Instead, some Runkit
functionality could be OO-ified and integrated into the Reflection API
(somewhere along the lines of [2] perhaps).
+1
A technical issue with your proposal you do not address are conflicts.
What happens when two classes overload the same class?
Why "including/parsing" order should not be taken into account ?
Beside that, the best thing you could to for the moment is to convince the
Zend framework guys to read up about Open Implementations[3].
Thanks for the link(s) !
--
Olivier Hoareau
PHP Best Pratices Evanglist
Bordeaux, France