Larry,

Thanks for the detailed reply. Just a few more questions and I think I can get this into the metamodel :)


On Jul 14, 2005, at 3:40 PM, Larry Wall wrote:
On Wed, Jul 13, 2005 at 07:27:52PM -0400, Stevan Little wrote:
: The way I am viewing the notion of "current class" for submethods
: currently is:
:
: From inside another method or submethod:
:
: - a submethod should only be called from the class which defines it.

This doesn't sound right to me.  There is no distinction between
inside or outside.

Yes, I am not sure what I was thinking there. Shortly after I wrote this mail I did some work on submethods in the metamodel and realized how silly that idea is :)

I also realized that a sepereate submethod dispatch table made no sense either, so scratch that thought out as well.

 A submethod is simply a method that says "These
aren't the droids you're looking for" if you call it via either SMD
or MMD dispatch and the first invocant isn't of the exact run-time
type of the lexical class.  In other words, it just has an implicit

    next METHOD if $?SELF != $?CLASS;

at the front. So the dispatch continues until it finds either a submethod
that does have an exact match or a method that isn't a submethod.

Now, the metamodel currently does not have MMD, and I think "next METHOD" is not as relevant in SMD. So would it make sense to do:

        next SUPER if $?SELF != $?CLASS;

or something like that? Here is some example code which might encounter this:

class Foo {
        method baz { ... }
}       

class Bar is Foo {
        submethod baz { ... }
}

class FooBar is Bar {}

my $foo_bar = FooBar.new();
$foo_bar.baz() # calls Foo::baz()

basically the dispatch goes from Bar::baz, which says "next SUPER" and the dispatcher then goes to Foo::baz since it is a method.

Is that correct?

: This means that since Object::bless() calls Object::BUILDALL() it is
: all well and good, assuming you have not overridden bless() in your
: class, and are calling it $class.bless().

No, Object::bless() (which perhaps delegates to Class.meta.bless so
that different meta classes can have different .bless primitives)

Okay, this makes sense.

calls MyClass.CREATE to create the type, while will be an opaque type
if that normal method dispatch runs up the tree to Object::CREATE.
(But user classes are allowed to define their own CREATE method to
create non-opaque objects.)

After the storage is allocated, .meta.bless then calls $newobj.BUILDALL
as an ordinary method call on the instance.  Again this is overridable
by each class, but typically goes back to Object::BUILDALL (which, as
usual, probably delegates at least some of the work to the meta class).

You refer to CREATE and BUILDALL as methods here, but A12 calls them submethods. Which is correct?

: (Object::BUILDALL of course then digs into the metaclass to call
: BUILD() for all the superclasses in post-order. I am not sure how to do
: that otherwise, submethod or not.)

I believe there's pseudo-code for that in A12.  The trick is that you
can always force a call to a submethod of the "wrong" class by taking
it as a sub reference and calling it like an ordinary subroutine.

Okay, this is just as dirty a trick as sneaking up into the metamodel, so I will leave it that way for now, knowing I need to change it later :)


: However, if you define MyClass::bless, then you will need to define
: MyClass::BUILDALL as well.

We did not intend that people redefined .bless. It's really intended to be a primitive like .meta. The occasional redefinables are CREATE and BUILDALL,
but it's really only intended that BUILD be defined typically.

Agreed, .bless should probably never be redefined, I will pull that up into the MetaClass.

<snip>

: > There's some kind of "yes I mean
: >you" notion in the dispatcher.  It comes out in user-visible terms
: >in .*foo calls but not ordinary .foo calls,
:
: I am not familiar with .*foo calls? Can you elaborate?

This is all pretty much straight from A12.

I see now, I forgot about those :)

: > which call a submethod
: >only when the object is actually that type, and otherwise look for an
: >ancestral method of that name.
:
: Yes, to expand upon my above statements. The method resolution would
: begin looking in the local submethod table, then move onto the local
: method table, and then on up the superclass hierarchy. Is that correct?

There is no separate submethod table.  From the standpoint of ordinary
.foo method resolution they're ordinary methods that happen to say
"next METHOD" as a form of failure.

Yup, realized that as soon as I tried to implement it :)

Thanks,

Stevan

Reply via email to