develooper Front page | perl.perl6.language | Postings from May 2004

Specifying class interfaces with AUTOMETH

Thread Next
From:
Austin Hastings
Date:
May 5, 2004 17:10
Subject:
Specifying class interfaces with AUTOMETH
Message ID:
ICELKKFHGNOHCNCCCBKFEEEGCMAA.Austin_Hastings@Yahoo.com
I was looking at *Unit the other day, and at the very satisfying "Mock
Objects" systems that have grown up around them for automated testing.

In a Decorator/delegation context, it seems like yet another case where
there's two ways to do things:

1- In(tro)spect the classes you want to replicate/extend and determine their
signature. Then 'eval' code that declares every single element of the
signature, usually just calling a helper function and then passing along the
call.

2- Use AUTOMETH[DEF] to implement a single point of code that catches the
method calls, handles whatever Expectations or Delegations exist, then
passes along the call:

  AUTOMETHDEF {
    return {
      check_expectations();
      check_preconditions();
      call();
      check_postconditions();
    };
  }

The benefits of option 2 is no 'eval', more straightforward code, etc.

The big drawback is that once you've extended a class in this fashion,
there's no knowing what your class' interface looks like from the outside.

How, then, would I go about specifying my 'intented' interface?

That is, I want to handle all or part of the interface via a switching
method like AUTOLOAD, but I want to let everyone inspect my class from
without and determine the actual supported method names, signatures, etc.

A12 is not clear on this point: it mentions (teasingly) AUTOMETH and
AUTOMETHDEF, but doesn't go into specifics.

From A12:  `Perl 6's version of .meta.can returns a "WALK"
            iterator for a set of routines that match the name.

           `... it [.meta.can] will exclude from the list of
            candidates any class that defines its own AUTOMETH
            method, on the assumption that each such AUTOMETH
            method has already had its chance to add any callable
            names to the list. If the class's AUTOMETH wishes to
            supply a method, it should return a reference to that
            method.ยด


From this, I infer that .meth.can (and dispatchery in general) will traverse
the class/role network looking for methods that match the request.

Apparently the AUTOMETH code will be invoked to determine what code matches
a request. AUTOMETH will "return a reference to" a matching method. This
implies that AUTOMETH is expected to resolve dispatch within the class --
"Here is the best answer I know."

This seems an awkward way to implement dispatch, since the price of using
AUTOMETH is being able to write a method dispatcher -- there won't be many
one-line AUTHMETH methods.

Also, it precludes having multiple candidates from a single source -- like
most "playoff" systems (but not the BCS :-).

Given that we've got a signature mechanism, it should be straightforward to
"declare" to dynwhat methods a class/role will respond. Thus, instead of a
interviewing a network of classes, the dispatcher could collect the data and
massage it in an appropriate fashion.

This has the side-benefit of solving my problem nicely: I can "declare" the
names to which I will respond, so that in(tro)spection will produce the
desired result, and so that invalid calls to my class can be caught before
being dispatched -- either at compile time or earlier in the runtime cycle.
(Even if they are only caught at runtime, they will at least be caught by
Perl itself rather than falling out the bottom of my switch statement.)

Comment?

=Austin


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About