On Sat, May 07, 2005 at 01:09:52PM -0400, Stevan Little wrote:
: Hello All,
: 
: So I am expanding our .isa() tests for built-in datatypes (in 
: particular Array), and I have a few (probably very simple) questions 
: (since I cannot seem to find details on this anywhere).
: 
: Is there an isa() built-in for this?
: 
: Or it is really @array.meta.isa() (from the Introspection section of 
: S12)?

The latter, I think, though probably it only redirects to .meta.isa when it
can't find .isa directly.  That is, Object.isa delegates to .meta.isa.
Unless it's Any.isa...

: According to S12/Introspection, isa() does 2 things:
: 
: (NOTE: this my interpretation since the details are not speced)
: 
: - If given no arguments (only an invocant), it returns a list of the 
: invocant's parent classes

Recursively?  That is, any classes for which .isa(X) would be true?

: - If given a class name as an argument, it returns a boolean (true if 
: invocant.isa(class) and false otherwise)

Yes.

: Now some questions about 'class name' argument described in the second 
: item above. (NOTE: I am asking general .isa() questions now, not just 
: about built-ins).
: 
: I assume it can be a Class name: $fido.isa(Dog)
: Or it can be a String:           $fido.isa('Dog')

That seems reasonable.  Note that ::Dog is equivalent to Dog in every
respect, including looking for a local definition of Dog before a global
one.

: But can it also be a Junction? :
:       $fido.isa(Dog | Cat)    # true if $fido.isa(Dog) or $fido.isa(Cat)
:       $fido.isa(Dog & Beagle) # true if $fide.isa(Dog) and 
:       $fido.isa(Beagle)

Autothreads, so .isa needn't worry about it.

: If it can be a Junction, it makes me wonder if maybe what is happening 
: behind the scenes is not some variant of the "smart-match" (~~).

Well, there aren't really variants of ~~, except insofar as people
add new MMD behaviors.  As for your question, it's more the other way
around, since ~~ is *almost* defined in terms of .isa.  (It's defined
in terms of .does instead, which with no argument produces a superset
of what .isa produces, since $x.does(X) is defined to be true for any
role X or parent class X or parent class's role X (or any subtype derived
from those for which the constraints are satisfied.  That implies .does
without arguments could get kind of expensive.)

Anyway, if inside .isa you try to do $obj ~~ $class, you'll just end up
turning .isa into a version of .does.  I think you probably need something
more like

    $obj.class =:= ::($class);

assuming symbolic references can also take hard refs.  Also, that's
not going to look up a string class starting in the correct package.
May have to separate out the string case and force lookup in the
caller's scope somehow.

In fact, I foresee this is going to be a general problem.  Maybe there
needs to be an optional argument to symbolic refs that specifies the
scope of the caller somehow, including both the lexical scope at the
point of the call and the package of the caller.

: In 
: that case, then would something like this DWIM (ignoring the 
: questionable sanity of actually doing it for a momemnt)
: 
:      @array.isa(@array)

Depends on what you mean.  Do you mean that @array contains a list of
types, or that @array is standing in for Array?  From your next example
it sounds like you mean the second of these:

    @array.isa(any(@array))
    @array.isa(@array.dispatcher)

: or even:
: 
:       @array.isa([]) # basically @array.isa(List)

That's not a List, it's an Array by the time .isa sees it.  You never
see a naked List in Perl unless you take specific steps to declare
a parameter to see it, or peek at an arrays .specs.

: However, maybe this is going to far :)

Well, it may fall out of the fact that the .dispatcher of either a class
or an object of the class is the class itself.

Larry

Reply via email to