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