Отражение (программирование)

Отражение (программирование)
  • Page 1 of 1
  • 1
Archive - read only
Отражение (программирование)
  1. WеniZAY
    WеniZAY
    1
    В информатике отражение или рефлексия (холоним интроспекции, англ. reflection) означает процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения. Парадигма программирования, положенная в основу отражения, называется рефлексивным программированием. Это один из видов метапрограммирования.

    В большинстве современных компьютерных архитектур программные инструкции (код) хранятся как данные. Разница между кодом и данными в том, что выполняя код, компьютеры обрабатывают данные. То есть инструкции выполняются, а данные обрабатываются так, как предписано этими инструкциями. Однако программы, написанные с помощью некоторых языков, способны обрабатывать собственные инструкции как данные и выполнять, таким образом, рефлексивные модификации. Такие самомодифицирующиеся программы в основном создаются с помощью высокоуровневых языков программирования, использующих виртуальные машины (например, Smalltalk, скриптовые языки). В меньшей степени рефлексия используется в языках с объявляемыми и/или статическими типами (например, Си, ML, Haskell, F#).
  • WеniZAY
    WеniZAY
    2
    Содержание
    1 Рефлексивно-ориентированное программирование
    2 История
    3 Применение
    4 Реализации
    5 Примеры
    5.1 C#
    5.2 ECMAScript
    5.3 Java
    5.4 Qt/C++
    5.5 Lua
    5.6 Objective-C
    5.7 Perl
    5.8 PHP
    5.9 Python
    5.10 Ruby
    5.11 Smalltalk
    5.12 Io
    5.13 ActionScript 3.0
    5.14 Delphi 2010
    1. WеniZAY
      WеniZAY
      3
      Рефлексивно-ориентированное программирование
      Рефлексивно-ориентированное программирование, или рефлексивное программирование — функциональное расширение парадигмы объектно-ориентированного программирования. Рефлексивно-ориентированное программирование включает в себя самопроверку, самомодификацию и самоклонирование. Тем не менее, главное достоинство рефлексивно-ориентированной парадигмы заключается в динамической модификации программы, которая может быть определена и выполнена во время работы программы. Некоторые императивные подходы, например, процедурная и объектно-ориентированная парадигмы программирования, указывают, что существует четкая предопределённая последовательность операций обработки данных. Парадигма рефлексивно-ориентированного программирования, тем не менее, добавляет возможность динамической модификации программных инструкций во время работы и их вызова в модифицированном виде. То есть программная архитектура сама определяет, что именно можно делать во время работы исходя из данных, сервисов и специфических операций.
  • WеniZAY
    WеniZAY
    4
    История
    Понятие рефлексии в языках программирования введено Brian Cantwell Smith в докторской диссертации 1982 г. наряду с понятием meta-circular interpreter, как компонента 3-Lisp.
    1. WеniZAY
      WеniZAY
      5
      Применение
      Рефлексия может использоваться для наблюдения и изменения программы во время выполнения. Рефлексивный компонент программы может наблюдать за выполнением определённого участка кода и изменять себя для достижения желаемой цели. Модификация выполняется во время выполнения программы путём динамического изменения кода.

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

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

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

    Реализация рефлексии на языках, её не поддерживающих, выполняется с помощью системы трансформации программы для автоматического отслеживания изменений исходного кода.
    1. WеniZAY
      WеniZAY
      7
      Примеры
      Следующие примеры иллюстрируют применение рефлексии на примере создания экземпляра foo класса Foo и вызова метода hello (или Hello) в различных языках программирования. Для каждого языка приведено по два примера: первый не использует рефлексию, а второй использует.
  • WеniZAY
    WеniZAY
    8
    C#

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

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

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

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

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

      // assuming that Foo resides in this
      new this['Foo']()['hello']()

      // or without assumption
      new (eval('Foo'))()['hello']()
  • WеniZAY
    WеniZAY
    10
    Java

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

    // С рефлексией
    Class foo = Class.forName("Foo");
    foo.getMethod("hello", null).invoke(foo.newInstance(), null);
    1. WеniZAY
      WеniZAY
      11
      Qt/C++
      Библиотека Qt расширяет возможности C++ с помощью метаязыка и обеспечивает поддержку рефлексии для ссылок на члены/методы класса и запрос имени объектов Qt с помощью класса QMetaObject, содержащего метаданные об объектах Qt.

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

      // С рефлексией
      QPushButton::staticMetaObject.className();  // "QPushButton"
  • WеniZAY
    WеniZAY
    12
    Lua

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

    -- С рефлексией
    _G['Foo']['hello']()
    1. WеniZAY
      WеniZAY
      13
      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];
  • WеniZAY
    WеniZAY
    14
    Perl

    Код
    # Без рефлексии
    my $foo = Foo->new();
    $foo->hello();

    # С рефлексией (используя синтаксис разыменовывания объектов)
    my $class  = "Foo";
    my $method = "hello";
    my $object = $class->new();
    $object->$method();
    1. WеniZAY
      WеniZAY
      15
      PHP

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

      //С рефлексией (используя ReflectionClass, введен в PHP5)
      $oReflector = new ReflectionClass('Foo');
      $oFoo = $oReflector->newInstance();
      $oHello = $oReflector->getMethod('hello');
      $oHello->invoke($oFoo);

      //С рефлексией (используя callback)
      $oFoo = new Foo();
      call_user_func(array($oFoo,'hello'));

      //С рефлексией (используя синтаксис разыменовывания объектов)
      $class_name = "Foo";
      $f = new $class_name();
      $method = "hello";
      $f->$method();
  • WеniZAY
    WеniZAY
    16
    Python

    Код
    # Без рефлексии
    Foo().hello()

    # С рефлексией
    getattr(globals()['Foo'](), 'hello')()
    1. WеniZAY
      WеniZAY
      17
      Ruby

      Код
      # Без рефлексии
      Foo.new.hello

      # С рефлексией
      Object.const_get(:Foo).send(:new).send(:hello)
  • WеniZAY
    WеniZAY
    18
    Smalltalk

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

    "С рефлексией"
    ((Smalltalk at: #Foo) perform: #new) perform: #hello
    1. WеniZAY
      WеniZAY
      19
      Io

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

      # Без рефлексии
      Foo hello

      # С рефлексией
      getSlot("Foo") getSlot("hello") call
  • WеniZAY
    WеniZAY
    20
    ActionScript 3.0

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

    // С рефлексией
    var cls:Object = getDefinitionByName("Foo");
    var foo:Object = new cls();
    foo["hello"]();
    1. WеniZAY
      WеniZAY
      21
      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.
    • Page 1 of 1
    • 1
    Search:
    Отражение (программирование)
    2018-2024 • WeniZAYTalk WeniZAY
    Запрещено использование материалов сайта без прямой ссылки на источник. Все права защищены.