龙蛇混杂是什么生肖
У информатици, рефлекси?а ?е способност неког рачунарског програма за испитива?е (види тип интроспекци?е) и измену сво?е структуре и понаша?а (конкретно вредности, мета-податке, особине и функци?е) у ранта?му.[1]
Истори?ска позадина
[уреди | уреди извор]На?рани?и рачунари су програмирани на матер?ем асемблер ?езику, ко?и су били по себи одражавани као ова оригинална архитектура ко?а може да се програмира дефиниса?ем инструкци?а као и кориш?е?ем података само-модифику?у?ег кода. Као програмира?е се преселило у ?езике високог нивоа, као што ?е C, ово одражава способност несталу (ван малвера) до програмских ?езика са одразом угра?еним у ?ихове типове система по?ава.
Бра?ан Кантвел Смитова 1982 докторска дисертаци?а[2][3] увела ?е по?ам рачунарске рефлекси?е у програмским ?езицима, као и по?ам мета-кружни преводилац као компонента 3-Lisp.
Примене
[уреди | уреди извор]Рефлекси?а може да се користи за посматра?е и допунава?е извршава?е програма на ранта?му. Рефлекси?а ори?ентисана програм компонента може пратити изврше?е ку?ишта кода и може се модификовати према же?еном ци?у у вези са тим ку?иштем. Ово се обично постиже динамичком доделом програмског кода у ранта?му.
У об?ектно ори?ентисаним програмским ?езицима као што су ?ава, рефлекси?а омогу?ава преглед класа, интерфе?са, по?а и метода у току рада не зна?у?и имена интерфе?са, по?а, метода компилаци?е. Она тако?е омогу?ава примерну нових об?еката и позива?е метода.
Рефлекси?а се тако?е може користити за адаптира?е датог програма у различитим ситуаци?ама динамике. На пример, размислите апликаци?у ко?а користи две различите класе X
и Y
наизменично да обав?а?у сличне операци?е. Без рефлекси?е ори?ентисаног програмира?а, апликаци?а може бити тешко кодирана да позове метод имена класеX
и класе Y
. Ме?утим, користе?и рефлекси?а ори?ентисану парадигму програмира?а, апликаци?а може бити диза?нирана и написана да искористи рефлекси?у у ци?у изазива?а метода у класама X
и Y
без хард-кодира?а имена метода. Рефлекси?а-ори?ентисано програмира?е скоро увек захтева додатно зна?е, оквир, релационо мапира?е, а об?екат релевантност како би се искористио више генеричко изврше?е кода.
Рефлекси?а се често користи као део тестира?а софтвера, као што ?е за ствара?е Ранта?ма/примена пробних об?еката.
Рефлекси?а ?е тако?е к?учна стратеги?а за метапрограмира?а.
У неким об?ектно-ори?ентисаним програмским ?езицима, као што су C# и ?ава, рефлекси?а може да се употреби да обори члан приступачног правила. На пример, рефлекси?а омогу?ава да промените вредност по?а са ознаком "приватно" у независну класу библиотеке.
Имплементаци?а
[уреди | уреди извор]?език за подршку рефлекси?е обезбе?у?е велики бро? функци?а ко?е су доступне на ранта?му ко?е би иначе било тешко пости?и у ?езику нижег нивоа. Неке од ових функци?а су могу?е до:
- Откри?те и модифику?е изворни код конструкци?а (као што ?е код блокова, класа, метода, протокола, итд) као об?екти прве класе на ранта?му.
- Претвара?е стринга ко?и одговара симболичком имену класе или функци?е у односу на или упу?ива?е на те класе или функци?е.
- Процените стринг као да ?е из?ава изворног кода у ранта?му.
- Креира?те нови тумач за ?език ба?тока да да нови смисао или ци? за програмира?е конструкта.
Ове карактеристике могу се реализовати на различите начине. У МОО-у, рефлекси?а представ?а природан део свакодневног програмира?а идиома. Када се зову глаголи (методе), разне вари?абле као што ?е глагол (име глагола ко?и се зове) и ово (предмет на ко?и се назива глагол) су насе?ени да да?у контекст позива. Безбедност обично управ?а приступом саговорничким штос програмно: Како ?е код саговорника () списак начина на ко?и се тренутни глагол на кра?у зову, изво?е?е тестова саговорника ()[1] (команде позива?у оригиналног корисника) омогу?ава да се глагол заштити од неовлаш?еног кориш?е?а.
Састав ?езика се осла?а на сво? ранта?м систем да пружи информаци?е о изворном коду. Састав Objective-C изврше?а, на пример, бележи имена свих метода у блок изврше?у, обезбе?у?у?и сто да одговара оним са основним методама (или селекторе за ове методе) састава у програму. У састав ?езика ко?и подржава ранта?м ствара?е функци?а, као што ?е Common Lisp, ранта?м окруже?е мора да садржи компа?лер или преводиоца.
Рефлекси?а се може реализовати за ?езике ко?и нема?у угра?ене рефлекси?е об?еката помо?у програма трансформаци?е система да дефинишу аутоматске промене изворног кода.
Примери
[уреди | уреди извор]Код следе?е код комади?и креира?у инстанцу foo
класе Foo
, и позива?у методу hello
. За сваки програмски ?език, нормала и рефлекси?а на бази секвенце позива се приказу?е.
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"
Види ?ош
[уреди | уреди извор]- Тип интроспекци?а
- Само-модифику?у?и код
- Само-дома?ински
- Парадигме програмира?а
- Листа рефлекту?у?их програмских ?езика и платформи
- Огледало (програмира?е)
Референце
[уреди | уреди извор]- ^ ?A Tutorial on Behavioral Reflection and its Implementation by Jacques Malenfant et al.” (PDF). Архивирано из оригинала (PDF) 22. 02. 2016. г. Приступ?ено 15. 01. 2016.
- ^ Brian Cantwell Smith, Procedural Reflection in Programming Languages, Department of Electrical Engineering and Computer Science, Massachusetts Institute of Technology, PhD Thesis, 1982.
- ^ ?Brian C. Smith. Reflection and semantics in a procedural language. Technical Report MIT-LCS-TR-272, Massachusetts Institute of Technology, Cambridge, Mass., January 1982.”. Архивирано из оригинала 13. 12. 2015. г. Приступ?ено 15. 01. 2016.
Литература
[уреди | уреди извор]- Jonathan M. Sobel and Daniel P. Friedman. An Introduction to Reflection-Oriented Programming (1996), Indiana University.
- Forman, Ira R.; Forman, Nate (2005). Java Reflection in Action. ISBN 978-1-932394-18-4.
- Forman, Ira R.; Danforth, Scott (1999). Putting Metaclasses to Work. ISBN 978-0-201-43305-0.
Спо?аш?е везе
[уреди | уреди извор]- Reflection in logic, functional and object-oriented programming: a short comparative study
- An Introduction to Reflection-Oriented Programming
- Brian Foote's pages on Reflection in Smalltalk
- Java Reflection API Tutorial from Oracle