From: David Simmons Date: 2001-08-09T05:18:04+09:00 Subject: [ruby-talk:19391] Re: Perl/Python/Ruby common backend (Parrot, can Ruby play too?) "Ned Konz" wrote in message news:Mvbc7.54318$WD1.3252627@e420r-atl2.usenetserver.com... > On Wednesday 08 August 2001 12:20 am, Piers Cawley wrote: > > Ned Konz writes: > >> Calling, say, $self->SUPER::method merely skips the > > > current class (and only works if written in the namespace (package) > > > of the class that's being defined, not dynamically as I've wanted it > > > to). > > > > Don't get me started on this. See the debate on the subject I had with > > perl5porters about a month back. And which, having looked up the > > SmallTalk way of doing it, I may be returning too. > > > > Annoyingly, there seems to be no way of implementing a reliable > > SUPER.pm which will do the right 'dynamic' thing, because perl doesn't > > cache the appropriate information when it makes the function call. > > In Class::Prototyped we ended up having to use closures to get "proper" super > behavior dynamically. Hmm. Being a Smalltalk implementor for the last decade or so... The smalltalk semantics for "super" are to "lookup" a method implementation by starting the message lookup from the "superclass" of the method-dictionary (class) in which the super/calling (method with the code using super) message is invoked. I.e., search from the superclass of the (super) calling method's behavior. In my latest Smalltalk implementation work, SmallScript, there is additional syntax for expressing that such a lookup begin at a particular class within the available set of superclasses of the method's behavior. Class name: A. Class name: B extends: A. Class name: C extends: B implements: I1, I2, I3. Class name: D extends: C implements: I4. Method behavior: C [ blah super blah. "implicitly searches starting at " super blah. "searches starting at " super blah. "searches starting at " ]. The above method would always behave identically for instances of either or . But, the internal mechanics are *not* statically bindable (they are statically cacheable which enables faster than vtable invocation). The reason it cannot be *statically* bound is that any operation at any time may change the shape of . I.e., during the course of program execution the superclass of may change, or it may have interfaces added or removed from its implements set. After all, classes are just objects. Note: Interfaces are mixins that can provide concrete structure (fields) as well as concrete (shared) behavior. They are not just "pure" specifications as seen in languages like java :) ----------------- QKS Smalltalk (SmallScript) provides first class namespaces and they play a role in the method binding process. [actually this is all defined by the virtual machines object model, and is not tied specifically to Smalltalk/SmallScript]. Thus I can declare a "scoped" method which can only be invoked by a caller who has dynamic access to that scope. Furthermore, in the face of multiple implementations existing in different scopes which the caller may have access to, the one chose will be the "best" fit based on scope distance from the scope of the message being bound to a method. Class name: K { Method scope: private [ blah ...only binds if callsite is a K method... ]. Method scope: Foo [ blah ...only binds if callsite has access to scope... ]. Method [ blah ...can bind from anywhere... ]. } "" Somewhere else, unrelated to prior code Module name: Foo { Eval [ |anObject| := SomeSharedVariableOrExpressionReturningA_K. anObject.blah(). "" Would implicitly invoke the variant anObject.#AOS.blah() "" Would explicitly invoke the unscoped variant ] } ================== Namespaces (scopes) simultaneously support both an inheritance (nested) and a mixin (agregate) model. All classes act as namespaces. Any given interfaces, modules, etc is just a class which supports the corresponding semantics for interfaces and modules. A given message bind to a given set of 0 or more methods is based on: a) Message scope (implicit or explicitly declared) b) The types of all the arguments (including the receiver or its surrogate -- #1,2,3 listed in the next paragraph) c) sandbox (execution scope) constraints d) special constraints for various message forms or bindings such as around, before, after behavior. Or managed objects delegation (on a per object basis), etc. The lookup process is through the MI lattice of: 1) an objects behavior tree 2) for super, the explicit behavior provided or implicit superclass behavior of the method's class. 3) a manager/prototype (per/instance) behavior tree. The actual process of looking for appropriate methods in the MI lattice is dynamic and operates through a multi-layer cache architecture that supports demand loading/linking and automatic method generation for implicit methods or foreign functions located externally or in distributed processes. ===================== So, a super lookup of a scoped message will do the right thing, even if the object is managed (delegated behavior/proxy etc). -- -- Dave S. [ http://smallscript.net ] Smalltalk for the AOS Platform and The Microsoft.NET Framework > > -- > Ned Konz > currently: Stanwood, WA > email: ned@bike-nomad.com > homepage: http://bike-nomad.com > >