Jump to content
 







Main menu
   


Navigation  



Main page
Contents
Current events
Random article
About Wikipedia
Contact us
Donate
 




Contribute  



Help
Learn to edit
Community portal
Recent changes
Upload file
 








Search  

































Create account

Log in
 









Create account
 Log in
 




Pages for logged out editors learn more  



Contributions
Talk
 



















Contents

   



(Top)
 


1 Examples  



1.1  Objective-C  





1.2  C++  





1.3  Object Pascal  





1.4  Java  





1.5  PHP  





1.6  Perl  



1.6.1  Meta-Object Protocol  







1.7  Python  





1.8  Ruby  





1.9  ActionScript  



1.9.1  Meta-type introspection  









2 See also  





3 References  





4 External links  














Type introspection






Español
Français
עברית
Polski
Português
Русский
Українська

 

Edit links
 









Article
Talk
 

















Read
Edit
View history
 








Tools
   


Actions  



Read
Edit
View history
 




General  



What links here
Related changes
Upload file
Special pages
Permanent link
Page information
Cite this page
Get shortened URL
Download QR code
Wikidata item
 




Print/export  



Download as PDF
Printable version
 
















Appearance
   

 






From Wikipedia, the free encyclopedia
 


Incomputing, type introspection is the ability of a program to examine the type or properties of an objectatruntime. Some programming languages possess this capability.

Introspection should not be confused with reflection, which goes a step further and is the ability for a program to manipulate the metadata, properties, and functions of an object at runtime. Some programming languages also possess that capability (e.g., Java, Python, Julia, and Go).

Examples[edit]

Objective-C[edit]

InObjective-C, for example, both the generic Object and NSObject (inCocoa/OpenStep) provide the method isMemberOfClass: which returns true if the argument to the method is an instance of the specified class. The method isKindOfClass: analogously returns true if the argument inherits from the specified class.

For example, say we have an Apple and an Orange class inheriting from Fruit.

Now, in the eat method we can write

- (void)eat:(id)sth {
    if ([sth isKindOfClass:[Fruit class]]) {
        // we're actually eating a Fruit, so continue
        if ([sth isMemberOfClass:[Apple class]]) {
            eatApple(sth);
        } else if ([sth isMemberOfClass:[Orange class]]) {
            eatOrange(sth);
        } else {
            error();
        }
    } else {
        error();
    }
}

Now, when eat is called with a generic object (anid), the function will behave correctly depending on the type of the generic object.

C++[edit]

C++ supports type introspection via the run-time type information (RTTI) typeid and dynamic_cast keywords. The dynamic_cast expression can be used to determine whether a particular object is of a particular derived class. For instance:

Person* p = dynamic_cast<Person *>(obj);
if (p != nullptr) {
  p->walk();
}

The typeid operator retrieves a std::type_info object describing the most derived type of an object:

if (typeid(Person) == typeid(*obj)) {
  serialize_person( obj );
}

Object Pascal[edit]

Type introspection has been a part of Object Pascal since the original release of Delphi, which uses RTTI heavily for visual form design. In Object Pascal, all classes descend from the base TObject class, which implements basic RTTI functionality. Every class's name can be referenced in code for RTTI purposes; the class name identifier is implemented as a pointer to the class's metadata, which can be declared and used as a variable of type TClass. The language includes an is operator, to determine if an object is or descends from a given class, an as operator, providing a type-checked typecast, and several TObject methods. Deeper introspection (enumerating fields and methods) is traditionally only supported for objects declared in the $M+ (a pragma) state, typically TPersistent, and only for symbols defined in the published section. Delphi 2010 increased this to nearly all symbols.

procedure Form1.MyButtonOnClick(Sender: TObject);
var
   aButton: TButton;
   SenderClass: TClass;
begin
   SenderClass := Sender.ClassType; //returns Sender's class pointer
   if sender is TButton then
   begin
      aButton := sender as TButton;
      EditBox.Text := aButton.Caption; //Property that the button has but generic objects don't
   end
   else begin
      EditBox.Text := Sender.ClassName; //returns the name of Sender's class as a string
   end;
end;

Java[edit]

The simplest example of type introspection in Java is the instanceof[1] operator. The instanceof operator determines whether a particular object belongs to a particular class (or a subclass of that class, or a class that implements that interface). For instance:

if (obj instanceof Person) {
    Person p = (Person)obj;
    p.walk();
}

The java.lang.Class[2] class is the basis of more advanced introspection.

For instance, if it is desirable to determine the actual class of an object (rather than whether it is a member of a particular class), Object.getClass() and Class.getName() can be used:

System.out.println(obj.getClass().getName());

PHP[edit]

InPHP introspection can be done using instanceof operator. For instance:

if ($obj instanceof Person) {
    // Do whatever you want
}

Perl[edit]

Introspection can be achieved using the ref and isa functions in Perl.

We can introspect the following classes and their corresponding instances:

package Animal;
sub new {
    my $class = shift;
    return bless {}, $class;
}

package Dog;
use base 'Animal';

package main;
my $animal = Animal->new();
my $dog = Dog->new();

using:

print "This is an Animal.\n" if ref $animal eq 'Animal';
print "Dog is an Animal.\n" if $dog->isa('Animal');

Meta-Object Protocol[edit]

Much more powerful introspection in Perl can be achieved using the Moose object system[3] and the Class::MOP meta-object protocol;[4] for example, you can check if a given object doesarole X:

if ($object->meta->does_role("X")) {
    # do something ...
}

This is how you can list fully qualified names of all of the methods that can be invoked on the object, together with the classes in which they were defined:

for my $method ($object->meta->get_all_methods) {
    print $method->fully_qualified_name, "\n";
}

Python[edit]

The most common method of introspection in Python is using the dir function to detail the attributes of an object. For example:

class Foo:
    def __init__(self, val):
        self.x = val

    def bar(self):
        return self.x
>>> dir(Foo(5))
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__str__', '__weakref__', 'bar', 'x']

Also, the built-in functions type and isinstance can be used to determine what an object is while hasattr can determine what an object does. For example:

>>> a = Foo(10)
>>> b = Bar(11)
>>> type(a)
<type 'Foo'>
>>> isinstance(a, Foo)
True
>>> isinstance(a, type(a))
True
>>> isinstance(a, type(b))
False
>>> hasattr(a, 'bar')
True

Ruby[edit]

Type introspection is a core feature of Ruby. In Ruby, the Object class (ancestor of every class) provides Object#instance_of? and Object#kind_of? methods for checking the instance's class. The latter returns true when the particular instance the message was sent to is an instance of a descendant of the class in question. For example, consider the following example code (you can immediately try this with the Interactive Ruby Shell):

$ irb
irb(main):001:0> A=Class.new
=>A
irb(main):002:0> B=Class.new A
=>B
irb(main):003:0> a=A.new
=> #<A:0x2e44b78>
irb(main):004:0> b=B.new
=> #<B:0x2e431b0>
irb(main):005:0> a.instance_of? A
=> true
irb(main):006:0> b.instance_of? A
=> false
irb(main):007:0> b.kind_of? A
=> true

In the example above, the Class class is used as any other class in Ruby. Two classes are created, A and B, the former is being a superclass of the latter, then one instance of each class is checked. The last expression gives true because A is a superclass of the class of b.

Further, you can directly ask for the class of any object, and "compare" them (code below assumes having executed the code above):

irb(main):008:0> A.instance_of? Class
=> true
irb(main):009:0> a.class
=>A
irb(main):010:0> a.class.class
=> Class
irb(main):011:0> A > B
=> true
irb(main):012:0> B <= A
=> true

ActionScript[edit]

InActionScript (as3), the function flash.utils.getQualifiedClassName can be used to retrieve the class/type name of an arbitrary object.

// all classes used in as3 must be imported explicitly
import flash.utils.getQualifiedClassName;
import flash.display.Sprite;
// trace is like System.out.println in Java or echo in PHP
trace(flash.utils.getQualifiedClassName("I'm a String")); // "String"
trace(flash.utils.getQualifiedClassName(1)); // "int", see dynamic casting for why not Number
trace(flash.utils.getQualifiedClassName(new flash.display.Sprite())); // "flash.display.Sprite"

Alternatively, the operator is can be used to determine if an object is of a specific type:

// trace is like System.out.println in Java or echo in PHP
trace("I'm a String" is String); // true
trace(1 is String); // false
trace("I'm a String" is Number); // false
trace(1 is Number); // true

This second function can be used to test class inheritance parents as well:

import flash.display.DisplayObject;
import flash.display.Sprite; // extends DisplayObject

trace(new flash.display.Sprite() is flash.display.Sprite); // true
trace(new flash.display.Sprite() is flash.display.DisplayObject); // true, because Sprite extends DisplayObject
trace(new flash.display.Sprite() is String); // false

Meta-type introspection[edit]

Like Perl, ActionScript can go further than getting the class name, but all the metadata, functions and other elements that make up an object using the flash.utils.describeType function; this is used when implementing reflection in ActionScript.

import flash.utils.describeType;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
import flash.display.Sprite;

var className:String = getQualifiedClassName(new flash.display.Sprite()); // "flash.display.Sprite"
var classRef:Class = getDefinitionByName(className); // Class reference to flash.display{{Not a typo|.}}Sprite
// eg. 'new classRef()' same as 'new  flash.display.Sprite()'
trace(describeType(classRef)); // return XML object describing type
// same as : trace(describeType(flash.display.Sprite));

See also[edit]

References[edit]

  • ^ Moose meta API documentation
  • ^ Class::MOP - a meta-object protocol for Perl
  • External links[edit]


    Retrieved from "https://en.wikipedia.org/w/index.php?title=Type_introspection&oldid=1227034089"

    Categories: 
    Object-oriented programming
    Programming language comparisons
    Hidden categories: 
    Wikipedia articles with style issues from December 2011
    All articles with style issues
    Articles with too many examples from December 2011
    All articles with too many examples
    Articles with multiple maintenance issues
    Articles with example C++ code
    Articles with example Java code
    Articles with example Objective-C code
    Articles with example Pascal code
    Articles with example Perl code
    Articles with example PHP code
    Articles with example Python (programming language) code
    Articles with example Ruby code
     



    This page was last edited on 3 June 2024, at 08:04 (UTC).

    Text is available under the Creative Commons Attribution-ShareAlike License 4.0; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization.



    Privacy policy

    About Wikipedia

    Disclaimers

    Contact Wikipedia

    Code of Conduct

    Developers

    Statistics

    Cookie statement

    Mobile view



    Wikimedia Foundation
    Powered by MediaWiki