This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Suggested isa() operator. =head1 VERSION Maintainer: James Mastros <[EMAIL PROTECTED]> Date: 08 Aug 2000 Version: 1 Mailing List: [EMAIL PROTECTED] Number: 77 =head1 ABSTRACT Currently, there is no way to determine if a scalar holds something that could validly form a number/Boolean/etc. This RFC seeks to remedy that. =head1 DESCRIPTION The suggested semantics of the isa operator are as follows: =over 4 =item $result = isa($obj, $type); TRUE VALUES: $result = "blessed" if $obj is blessed into the package $type. $result = "inherits(n)" if $obj is blessed into a package that ISA $type in the Nth degree. $result = "is a" if $obj currently has a $type value associated with it. $result = "can be a" if $obj could be promoted to a $type value. $result = "tied to a" if $obj is tied to (something which inherits from) $type. FALSE VALUES: $result = 0 if $obj is not a $type, but $type is a known package or basic type. $result = undef if $type is not a known package or basic type. in all cases, if $type is a blessed ref, it should be taken as if ref($type) had been specified. An unholy ref is invalid for $type. =back This is incompatible with UNIVERSAL::isa() in one case: if $obj is a string containing the name of a package, the current C<UNIVERSAL::isa($obj, $type)> will do what the proposed C<isa(bless(\0, $obj), $type)> would do. This, fortunately, would not be automatically convertible. Therefore, it might be better to have the existing semantics apply to C<isa($obj, $type)> when $obj holds the name of an existing package. Unfortunately, this means that you cannot apply isa() to arbitrary strings in absolute safety. FIXME. =over 4 =item @result = isa($obj, $type); @result is the lineage of $obj that leads to $type. More exactly, it is a list such that C<isa(bless(\0, $result[i]), $result[i-1]) =~ s/^inherits/>. (Hmm, perhaps things like that are a good argument for why isa should treat $obj=a package name specialy.) Also, the list will always either be empty (if C<scalar(isa($obj, $type))> is false), or will end in (the cannonical form, if there is some noncannonical form of package names or basic types). =item $result = isa($obj); $result is the basic type of $obj -- "INTEGER", "NUMBER", "STRING", "REF", "FILEHANDLE", etc. This is it's most specific IS_xOK() (or similar) type (INTEGER winning over NUMBER, which wins over STRING, FILEHANDLE winning over REF, if they end up being different basic types). Note that this doesn't dereference $obj or give the type it is blessed into; ref() is for that. (If you want to know the basic type of the object that it points to, even if it is blessed, see the next form.) =item @result = isa($obj); This will follow the chain of refs, giving a list of the packages, etc, of each, as well as going into lists and hashes. For example: my $foo = [14, "21"]; my $bar = bless (\$foo, "Example::Package1"); my $baz = bless (\$bar, "Example::Package2"); print Data::Dumper \(isa($baz)); Will print (assuming I got the parentheses right on that last line): ("Example::Package2", "Example::Pacakge1", "LIST", ["INTEGER", "STRING"]) Note that the last element is a ref to the list that doing a list of scalar(isa($thingies)) on the thingy that has it's type mentioned in the -2th element. This has the possibility of producing very deep (even infinitely deep/self-referencing) lists, and should possibly be limited to the return of the scalar form, or omitted entirely. However, completely eliminating it would mean that you couldn't find the types of a list of items by doing isa(\@list). FIXME. Also, I'm not sure what to do about tied thingies, since things can be tied, blessed, and have subvalues all at the same time. FIXME. This would have to stop somewhere with recursive and infinite (including non-terminating ties, infinite, and semi-finite lists/hashes) structures. FIXME. Note also that this has the list at the end returning the current basic type instead of the most specific possible basic type. FIXME. =back =head1 IMPLEMENTATION Hmm, it's natively (and naïveté) recursive. =head1 UNRESOLVED ISSUES C<m/FIXME/>. =head1 REFERENCES L<UNIVERSAL> for UNIVERSAL::isa compatibility L<ref>