Отражение (программирование) | это... Что такое Отражение (программирование)? (original) (raw)


Шаблон: Просмотр • информатике отражение или рефлексия (синоним интроспекция, англ. reflection) означает процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения. Парадигма программирования, положенная в основу отражения, называется рефлексивным программированием. Это один из видов метапрограммирования[1].

В большинстве современных компьютерных архитектур программные инструкции (код) хранятся как данные. Разница между кодом и данными в том, что выполняя код, компьютеры обрабатывают данные. То есть инструкции выполняются, а данные обрабатываются так, как предписано этими инструкциями. Однако программы, написанные с помощью некоторых языков, способны обрабатывать собственные инструкции как данные и выполнять, таким образом, рефлексивные модификации. Такие самомодифицирующиеся программы в основном создаются с помощью высокоуровневых языков программирования, использующих виртуальные машины (например, Smalltalk, скриптовые языки). В меньшей степени рефлексия используется в языках с объявляемыми и/или статическими типами (например, Java, Си, ML, Haskell).

Содержание

Рефлексивно-ориентированное программирование

Рефлексивно-ориентированное программирование, или рефлексивное программирование — функциональное расширение парадигмы объектно-ориентированного программирования. Рефлексивно-ориентированное программирование включает в себя самопроверку, самомодификацию и самоклонирование. Тем не менее, главное достоинство рефлексивно-ориентированной парадигмы заключается в динамической модификации программы, которая может быть определена и выполнена во время работы программы. Некоторые императивные подходы, например, процедурная и объектно-ориентированная парадигмы программирования, указывают, что существует четкая предопределённая последовательность операций обработки данных. Парадигма рефлексивно-ориентированного программирования, тем не менее, добавляет возможность динамической модификации программных инструкций во время работы и их вызова в модифицированном виде. То есть программная архитектура сама определяет, что именно можно делать во время работы исходя из данных, сервисов и специфических операций.

История

Понятие рефлексии в языках программирования введено Brian Cantwell Smith в докторской диссертации 1982 г.[2][3] наряду с понятием meta-circular interpreter, как компонента 3-Lisp.

Применение

Рефлексия может использоваться для наблюдения и изменения программы во время выполнения. Рефлексивный компонент программы может наблюдать за выполнением определённого участка кода и изменять себя для достижения желаемой цели. Модификация выполняется во время выполнения программы путём динамического изменения кода.

Рефлексию можно применять и для динамической адаптации программы к различным ситуациям. Например, рассмотрим программу, использующую два разных класса X и Y для выполнения аналогичных операций. Без рефлексии в коде программы методы классов X и Y будут вызываться явно. Если программа спроектирована с применением рефлексивно-ориентированный парадигмы программирования, некоторый участок кода не будет содержать явных вызовов методов классов X и Y; программа выполнит этот участок дважды: сначала для класса X, затем для класса Y.

Реализации

Программы, написанные на языках программирования, поддерживающих рефлексию, наделены дополнительными возможностями, реализация которых на языках низкого уровня затруднительна. Перечислим некоторые из них:

Реализация этих возможностей возможна разными путями. В языке MOO рефлексия является частью ежедневной идиомы программирования. Все вызываемые методы получают в контексте информацию о том, откуда они вызваны, и ссылки на объекты, к которым они принадлежат. Безопасность контролируется программно с помощью стека вызовов: вызывается callers() для получения списка методов; проверяется, не заблокировал ли callers()[1] сам себя.

Компилируемые языки полагаются на свои системы выполнения, обеспечивающие программы информацией о их исходном коде. Скомпилированный на Objective-C выполняемый файл, например, записывает имена всех методов в один блок, создаёт таблицу соответствия. В компилируемых языках, поддерживающих создание функций во время выполнения, таких как Common Lisp, среда выполнения должна включать компилятор и интерпретатор.

Реализация рефлексии на языках, её не поддерживающих, выполняется с помощью системы трансформации программы для автоматического отслеживания изменений исходного кода.

Примеры

Следующие примеры иллюстрируют применение рефлексии на примере создания экземпляра foo класса Foo и вызова метода hello (или Hello) в различных языках программирования. Для каждого языка приведено по два примера: первый не использует рефлексию, а второй использует.

C#

// Без рефлексии new Foo().Hello();

// С рефлексией Type type=System.Type.GetType("Foo"); var foo=Activator.CreateInstance(type); foo.GetType().GetMethod("Hello").Invoke(foo, null);

ECMAScript

Также работает на JavaScript и ActionScript:

//Без рефлексии new Foo().hello()

// С рефлексией

// assuming that Foo resides in this new this'Foo''hello'

// or without assumption new (eval('Foo'))()'hello'

Java

// Без рефлексии new Foo().hello();

// С рефлексией Class cls = Class.forName("Foo"); cls.getMethod("hello", null).invoke(cls.newInstance(), null);

Qt/C++

Библиотека Qt расширяет возможности C++ с помощью метаязыка и обеспечивает поддержку рефлексии для ссылок на члены/методы класса и запрос имени объектов Qt с помощью класса QMetaObject, содержащего метаданные об объектах Qt.

// Без рефлексии QObject *obj = new QPushButton; obj->metaObject()->className(); // "QPushButton"

// С рефлексией QPushButton::staticMetaObject.className(); // "QPushButton"

Lua

-- Без рефлексии Foo.hello()

-- С рефлексией _G['Foo']'hello'

Objective-C

// Без рефлексии Foo *foo = [[Foo alloc] init]; [foo hello];

// С рефлексией Class cls = NSClassFromString(@"Foo"); id foo = [[cls alloc] init]; SEL selector = NSSelectorFromString(@"hello"); [foo performSelector:selector withObject:nil];

Perl

Без рефлексии

my $foo = Foo->new(); $foo->hello();

С рефлексией

my $class = "Foo"; my $method = "hello"; my object=object = object=class->new(); object−>object->object>method();

PHP

//Без рефлексии $oFoo = new Foo(); $oFoo->hello();

//С рефлексией $oReflector = new ReflectionClass('Foo'); oFoo=oFoo = oFoo=oReflector->newInstance(); oHello=oHello = oHello=oReflector->getMethod('hello'); oHello−>invoke(oHello->invoke(oHello>invoke(oFoo);

//С использованием callback $oFoo = new Foo(); call_user_func(array($oFoo,'hello'));

//С использованием синтаксиса переменных переменных $class_name = "Foo"; f=newf = new f=newclass_name(); $method = "hello"; f−>f->f>method();

Python

Без рефлексии

Foo().hello()

С рефлексией

getattr(globals()'Foo', 'hello')()

Ruby

Без рефлексии

Foo.new.hello

С рефлексией

Object.const_get(:Foo).send(:new).send(:hello)

Smalltalk

"Без рефлексии" Foo new hello

"С рефлексией" ((Smalltalk at: #Foo) perform: #new) perform: #hello

Io

Foo := Object clone do( hello := method( "Hello" println ) )

Без рефлексии

Foo hello

С рефлексией

getSlot("Foo") getSlot("hello") call

ActionScript 3.0

// Без рефлексии var foo:Foo = new Foo(); foo.hello();

// С рефлексией var cls:Object = getDefinitionByName("Foo"); var foo:Object = new cls(); foo."hello";

Delphi 2010

// Без рефлексии var foo : TFoo; begin foo := TFoo.Create(); foo.Hello(); end;

// С рефлексией var c : TRttiContext; t : TRttiInstanceType; foo : TValue; begin c := TRttiContext.Create; t := (c.FindType('TFoo') as TRttiInstanceType); foo := t.GetMethod('Create').Invoke(t.MetaclassType,[]); t.GetMethod('Hello').Invoke(foo,[]); c.Free; end.

См. также

Ссылки

Notes

  1. Руководство Мета Халлбата англ. Matt Hurlbutt по поведенческой рефлексии и её реализации (англ.)
  2. , кандидатская диссертация, «Процедурная рефлексия в языках программирования», Массачусетский технологический институт, факультет электротехники и информатики, 1982 (англ.)
  3. Brian C. Smith. Рефлексия и семантики в процедурных языках программирования. Служебный отчёт MIT-LCS-TR-272, Массачусетский технологический институт, Кембридж, Mass., январь 1982 (англ.)

Documents

Дополнительная информация

Ссылки

Категория:

Wikimedia Foundation.2010.

Полезное

Смотреть что такое "Отражение (программирование)" в других словарях: