Рефлексија (програмирање)У информатици, рефлексија је способност неког рачунарског програма за испитивање (види тип интроспекције) и измену своје структуре и понашања (конкретно вредности, мета-податке, особине и функције) у рантајму.[1] Историјска позадинаНајранији рачунари су програмирани на матерњем асемблер језику, који су били по себи одражавани као ова оригинална архитектура која може да се програмира дефинисањем инструкција као и коришћењем података само-модификујућег кода. Као програмирање се преселило у језике високог нивоа, као што је C, ово одражава способност несталу (ван малвера) до програмских језика са одразом уграђеним у њихове типове система појава. Брајан Кантвел Смитова 1982 докторска дисертација[2][3] увела је појам рачунарске рефлексије у програмским језицима, као и појам мета-кружни преводилац као компонента 3-Lisp. ПрименеРефлексија може да се користи за посматрање и допунавање извршавање програма на рантајму. Рефлексија оријентисана програм компонента може пратити извршење кућишта кода и може се модификовати према жељеном циљу у вези са тим кућиштем. Ово се обично постиже динамичком доделом програмског кода у рантајму. У објектно оријентисаним програмским језицима као што су Јава, рефлексија омогућава преглед класа, интерфејса, поља и метода у току рада не знајући имена интерфејса, поља, метода компилације. Она такође омогућава примерну нових објеката и позивање метода. Рефлексија се такође може користити за адаптирање датог програма у различитим ситуацијама динамике. На пример, размислите апликацију која користи две различите класе Рефлексија се често користи као део тестирања софтвера, као што је за стварање Рантајма/примена пробних објеката. Рефлексија је такође кључна стратегија за метапрограмирања. У неким објектно-оријентисаним програмским језицима, као што су C# и Јава, рефлексија може да се употреби да обори члан приступачног правила. На пример, рефлексија омогућава да промените вредност поља са ознаком "приватно" у независну класу библиотеке. ИмплементацијаЈезик за подршку рефлексије обезбеђује велики број функција које су доступне на рантајму које би иначе било тешко постићи у језику нижег нивоа. Неке од ових функција су могуће до:
Ове карактеристике могу се реализовати на различите начине. У МОО-у, рефлексија представља природан део свакодневног програмирања идиома. Када се зову глаголи (методе), разне варијабле као што је глагол (име глагола који се зове) и ово (предмет на који се назива глагол) су насељени да дају контекст позива. Безбедност обично управља приступом саговорничким штос програмно: Како је код саговорника () списак начина на који се тренутни глагол на крају зову, извођење тестова саговорника ()[1] (команде позивају оригиналног корисника) омогућава да се глагол заштити од неовлашћеног коришћења. Састав језика се ослања на свој рантајм систем да пружи информације о изворном коду. Састав Objective-C извршења, на пример, бележи имена свих метода у блок извршењу, обезбеђујући сто да одговара оним са основним методама (или селекторе за ове методе) састава у програму. У састав језика који подржава рантајм стварање функција, као што је Common Lisp, рантајм окружење мора да садржи компајлер или преводиоца. Рефлексија се може реализовати за језике који немају уграђене рефлексије објеката помоћу програма трансформације система да дефинишу аутоматске промене изворног кода. ПримериКод следеће код комадићи креирају инстанцу eCУ наставку је пример у eC-у: // без рефлексије
Foo foo { };
foo.hello();
// са рефлексијом
Class fooClass = eSystem_FindClass(__thisModule, "Foo");
Instance foo = eInstance_New(fooClass);
Method m = eClass_FindMethod(fooClass, "hello", fooClass.module);
((void (*)())(void *)m.function)(foo);
ECMAScriptУ наставку је пример у ECMAScript-у, и стога важи и за Јаваскрипт и ActionScript: // без рефлексије
new Foo.hello()
// са рефлексијом
// под претпоставком да Foo борави у овде
new this['Foo']['hello']()
// или без претпоставке
new (eval('Foo'))['hello']()
// или једноставно
eval('new Foo.hello()')
ЈаваУ наставку је пример у Јави: // без рефлексије
Foo foo = new Foo();
foo.hello();
// са рефлексијом
Object foo = Class.forName("complete.classpath.and.Foo").newInstance();
// Алтернативно: Објекат foo = Foo.class.newInstance();
Method m = foo.getClass().getDeclaredMethod("hello", new Class<?>[0]);
m.invoke(foo);
Objective-CСледећи пример у Objective-C-у имплицира OpenStep или се користи фондација Кит оквир: // Foo класа.
@interface Foo : NSObject
- (void)hello;
@end
// Слање "здраво" на пример Foo без рефлексије.
Foo *obj = [[Foo alloc] init];
[obj hello];
// Слање "здраво" на пример Фоо са рефлексијом.
id obj = [[NSClassFromString(@"Foo") alloc] init];
[obj performSelector: @selector(hello)];
ДелфиОвај Делфи пример претпоставља да TFoo класа је декларисана у јединици под називом Јединица 1: uses RTTI, Unit1;
procedure WithoutReflection;
var
Foo: TFoo;
begin
Foo := TFoo.Create;
try
Foo.Hello;
finally
Foo.Free;
end;
end;
procedure WithReflection;
var
RttiContext: TRttiContext;
RttiType: TRttiInstanceType;
Foo: TObject;
begin
RttiType := RttiContext.FindType('Unit1.TFoo') as TRttiInstanceType;
Foo := RttiType.GetMethod('Create').Invoke(RttiType.MetaclassType, []).AsObject;
try
RttiType.GetMethod('Hello').Invoke(Foo, []);
finally
Foo.Free;
end;
end;
Ово је значајан пример, јер Делфи је без менаџера, потпуно природно састављен језик, за разлику од већине других језика који подржавају размишљање. Његова архитектура језика наслеђује од снажног-откуцаног Паскала, али са значајним утицајем од SmallTalk-а. Упоредите са осталим примерима овде, од којих су многи динамични или скрипте језици као што су Perl, Пајтон или PHP или језици са рантајма као Јава или C#. PerlУ наставку је пример у Perl-у: # без рефлексије
my $foo = Foo->new;
$foo->hello;
# или
Foo->new->hello;
# са рефлексијом
my $class = "Foo"
my $constructor = "new";
my $method = "hello";
my $f = $class->$constructor;
$f->$method;
# или
$class->$constructor->$method;
# са eval-ом
eval "new Foo->hello;";
PHPУ наставку је пример у PHP-у: // без рефлексије
$foo = new Foo();
$foo->hello();
// са рефлексијом
$reflector = new ReflectionClass('Foo');
$foo = $reflector->newInstance();
$hello = $reflector->getMethod('hello');
$hello->invoke($foo);
// коришћење повратних позива
$foo = new Foo();
call_user_func(array($foo, 'hello'));
// коришћењем променљиве варијабле синтаксе
$className = 'Foo';
$foo = new $className();
$method = 'hello';
$foo->$method();
ПајтонУ наставку је пример у Пајтону: # без рефлексије
obj = Foo()
obj.hello()
# са рефлексијом
class_name = "Foo"
method = "hello"
obj = globals()[class_name]()
getattr(obj, method)()
# са eval-ом
eval("Foo().hello()")
RУ наставку је пример у R-у: # Без рефлексије, под претпоставком да foo () враћа С3-тип објекат који има методу "здраво"
obj <- foo()
hello(obj)
# са рефлексијом
the.class <- "foo"
the.method <- "hello"
obj <- do.call(the.class, list())
do.call(the.method, alist(obj))
RubyУ наставку је пример у Рубију: # без рефлексије
obj = Foo.new
obj.hello
# са рефлексијом
class_name = "Foo"
method = :hello
obj = Object.const_get(class_name).new
obj.send method
# са eval-ом
eval "Foo.new.hello"
Види још
Референце
Литература
Спољашње везе
|
Portal di Ensiklopedia Dunia