برنامهنویسی پژواکی
در علوم رایانه، پژواک (به انگلیسی: Reflection) توانایی یک پردازه برای آزمون، خوداندیشی، و اصلاح «ساختار» و «رفتار» داخلی خودش میباشد.[۱]
کاربردها[ویرایش]
- پژواک به برنامهنویس کمک میکند تا کتابخانههای نرمافزاری همگانی بسازد که هدف آن میتواند: نمایش داده، پردازش قالبهای مختلف داده، انجام سریال سازی، یا انجام بازگشت سریال سازی داده برای ارتباطات، یا بستهبندی یا جداسازی از بسته برای داده برای ارتباطات ظرف دهی شده یا ارتباطات انفجاری باشد.[۲]
- استفاده از پژواک به زبان کمک میکند تا برای کدهای «مبتنی-بر-شبکه» مناسب باشد.[۲]
- از پژواک برای مشاهده و اصلاح اجرای برنامه، در «زمان اجرا» استفاده میشود.[۲]
- در زبانهای برنامهنویسی شی گرا مثل جاوا، پژواک امکان بازرسی کلاسها، واسطها، فیلدها، و متدها را در زمان اجرا میدهد، حتی اگر نام واسطها، فیلدها، و متدها در زمان کامپایل را ندانیم. این موضوع امکان نمونه برداری از اشیای جدید و فراخوانی متدها را میدهد.[۲]
- از پژواک معمولاً به عنوان بخشی از آزمون نرمافزار، استفاده میشود، مثلاً برای ساخت/نمونه برداری از اشیای ساختگی.[۲]
- پژواک یک استراتژی کلیدی برای فرا برنامهنویسی است.[۲]
- در بعضی از زبانهای برنامهنویسی شی گرا، مثل سی شارپ، و جاوا، از پژواک میتوان در انتقال قواعد دسترسی عضو استفاده کرد.[۲]
استفادهٔ مؤثر از پژواک، تقریباً همیشه نیاز به یک برنامه دارد: یک چهارچوب طراحی، توصیف کد دهی، کتابخانه شیی، یا تناظر یک پایگاه داده یا ارتباطات موجودیت.[۲]
پیادهسازی[ویرایش]
یک زبان پشتیبانی کننده از پژواک، ویژگیهایی را تدارک میبیند که در «زمان اجرا» استفاده میشوند، اگر این ویژگیها وجود نداشته باشد، پیادهسازی پژواک در زبانهای سطح پایین بسیار سخت است.[۲]
بعضی از این ویژگیها، در ادامه ذکر میشوند، توانایی برای:
- تشخیص و اصلاح ساختمانهای کد منبع (مثل بلاک کد، کلاسها، متدها، پروتکلها و غیره) به عنوان اشیای کلاس سطح اول، در زمان اجرا.
- تبدیل یک رشته که با نام نمادین یک کلاس یا تابع منطبق است به یک ارجاع (reference) یا به فراخوانی (invocation) آن کلاس یا تابع.
- یک رشته، را بتوان به صورت یک عبارت کد منبع در زمان اجرا ارزیابی کرد.
- تولید یک مفسر جدید برای بایتکد یک زبان، که در این قابلیت، مقصود ایجاد یک معنی جدید یا هدف جدید برای یک ساختار برنامهنویسی میباشد.[۲]
مثالها[ویرایش]
قطعه کدهایی که در ادامه میآیند یک نمونه foo از کلاس Foo را میسازند، و متد PrintHello آن را فراخوانی میکنند. برای هر زبان برنامهنویسی، ترتیب صدا زدن نرمال و مبتنی بر پژواک نشان داده شدهاست.[۲]
سی شارپ[ویرایش]
در ادامه یک مثال به زبان سی شارپ آمدهاست:
// Without reflection Foo foo = new Foo(); foo.PrintHello(); // With reflection Object foo = Activator.CreateInstance("complete.classpath.and.Foo"); MethodInfo method = foo.GetType().GetMethod("PrintHello"); method.Invoke(foo, null);
دلفی[ویرایش]
این مثال دلفی فرض کردهاست که یک کلاس TFoo در یک واحد که Unit1 نام دارد، اعلام شدهاست:
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;
زبان ایسی[ویرایش]
در ادامه یک مثال در زبان eC آمدهاست:
// Without reflection Foo foo { }; foo.hello(); // With reflection 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 آمدهاست، و بنابراین به JavaScript و ActionScript اعمال میشود:
// Without reflection new Foo().hello() // With reflection // assuming that Foo resides in this new this['Foo']()['hello']() // or without assumption new (eval('Foo'))()['hello']() // or simply eval('new Foo().hello()') // Using ECMAScript 2015's new Reflect class: Reflect.construct(Foo, [])['hello']()
Go[ویرایش]
در ادامه یک مثال به زبان Go آمدهاست:
import "reflect" // Without reflection f := Foo{} f.Hello() // With reflection fT := reflect.TypeOf(Foo{}) fV := reflect.New(fT) m := fV.MethodByName("Hello") if m.IsValid() { m.Call(nil) }
جاوا[ویرایش]
در ادامه یک مثال به زبان جاوا آمدهاست:
import java.lang.reflect.Method; // Without reflection Foo foo = new Foo(); foo.hello(); // With reflection try { // Alternatively: Object foo = Foo.class.newInstance(); Object foo = Class.forName("complete.classpath.and.Foo").newInstance(); Method m = foo.getClass().getDeclaredMethod("hello", new Class<?>[0]); m.invoke(foo); } catch (Exception e) { // Catching ClassNotFoundException, NoSuchMethodException // InstantiationException, IllegalAccessException }
Objective-C[ویرایش]
در ادامه یک مثال در Objective-C آمدهاست، و معنی ضمنی میدهد که یا چهارچوب OpenStep یا Foundation Kit استفاده شدهاست:
// Foo class. @interface Foo : NSObject - (void)hello; @end // Sending "hello" to a Foo instance without reflection. Foo *obj = [[Foo alloc] init]; [obj hello]; // Sending "hello" to a Foo instance with reflection. id obj = [[NSClassFromString(@"Foo") alloc] init]; [obj performSelector: @selector(hello)];
Perl[ویرایش]
در ادامه یک مثال در زبان پرل آمدهاست:
# Without reflection my $foo = Foo->new; $foo->hello; # or Foo->new->hello; # With reflection my $class = "Foo" my $constructor = "new"; my $method = "hello"; my $f = $class->$constructor; $f->$method; # or $class->$constructor->$method; # with eval eval "new Foo->hello;";
PHP[ویرایش]
در ادامه یک مثال به زبان PHP آمدهاست:
// Without reflection $foo = new Foo(); $foo->hello(); // With reflection, using Reflections API $reflector = new ReflectionClass('Foo'); $foo = $reflector->newInstance(); $hello = $reflector->getMethod('hello'); $hello->invoke($foo);
پایتون[ویرایش]
در ادامه یک مثال در زبان پایتون آمدهاست:
# Without reflection obj = Foo() obj.hello() # With reflection obj = globals()['Foo']() getattr(obj, 'hello')() # With eval eval('Foo().hello()')
R[ویرایش]
در ادامه یک مثال به زبان R آمدهاست:
# Without reflection, assuming foo() returns an S3-type object that has method "hello" obj <- foo() hello(obj) # With reflection the.class <- "foo" the.method <- "hello" obj <- do.call(the.class, list()) do.call(the.method, alist(obj))
Ruby[ویرایش]
در ادامه یک مثال به زبان روبی آمدهاست:
# Without reflection obj = Foo.new obj.hello # With reflection class_name = "Foo" method_name = :hello obj = Object.const_get(class_name).new obj.send method_name # With eval eval "Foo.new.hello"
Xojo[ویرایش]
در ادامه یک مثال با استفاده از Xojo آمدهاست:
' Without reflection Dim fooInstance As New Foo fooInstance.PrintHello ' With reflection Dim classInfo As Introspection.Typeinfo = GetTypeInfo(Foo) Dim constructors() As Introspection.ConstructorInfo = classInfo.GetConstructors Dim fooInstance As Foo = constructors(0).Invoke Dim methods() As Introspection.MethodInfo = classInfo.GetMethods For Each m As Introspection.MethodInfo In methods If m.Name = "PrintHello" Then m.Invoke(fooInstance) End If Next
منابع[ویرایش]
- ↑ A Tutorial on Behavioral Reflection and its Implementation by Jacques Malenfant et al. (PDF), unknown, archived from the original (PDF) on 21 August 2017, retrieved 23 June 2019
- ↑ ۲٫۰۰ ۲٫۰۱ ۲٫۰۲ ۲٫۰۳ ۲٫۰۴ ۲٫۰۵ ۲٫۰۶ ۲٫۰۷ ۲٫۰۸ ۲٫۰۹ ۲٫۱۰ "Reflection (computer programming)". Wikipedia (به انگلیسی). 2019-12-30.