البرمجة الانعكاسية

في علوم الكمبيوتر ، البرمجة التأملية أو التأمل هي قدرة العملية على فحص وتأمل وتعديل بنيتها وسلوكها. [1]

الخلفية التاريخية

كانت أجهزة الكمبيوتر الأولى مبرمجة بلغات التجميع الأصلية الخاصة بها ، والتي كانت عاكسة بطبيعتها، حيث يمكن برمجة هذه البنيات الأصلية من خلال تعريف التعليمات كبيانات واستخدام كود قابل للتعديل ذاتيًا . ومع انتقال الجزء الأكبر من البرمجة إلى لغات تجميعية عالية المستوى مثل Algol و Cobol و Fortran و Pascal و C ، اختفت هذه القدرة العاكسة إلى حد كبير حتى ظهرت لغات برمجة جديدة مع انعكاس مدمج في أنظمة الكتابة الخاصة بها. [ بحاجة لمصدر ]

قدمت أطروحة الدكتوراه التي قدمها برايان كانتويل سميث عام 1982 مفهوم الانعكاس الحسابي في لغات البرمجة الإجرائية ومفهوم المترجم الدائري كمكون من مكونات 3-Lisp. [2] [3]

الاستخدامات

يساعد الانعكاس المبرمجين على إنشاء مكتبات برمجية عامة لعرض البيانات، ومعالجة تنسيقات مختلفة من البيانات، وإجراء تسلسل وإلغاء تسلسل البيانات من أجل الاتصال، أو تجميع وفصل البيانات للحاويات أو دفعات الاتصال.

يتطلب الاستخدام الفعال للتأمل دائمًا تقريبًا خطة: إطار تصميم، أو وصف ترميز، أو مكتبة كائنات، أو خريطة لقاعدة بيانات، أو علاقات الكيان.

يجعل الانعكاس اللغة أكثر ملاءمة للكود الموجه للشبكات. على سبيل المثال، يساعد لغات مثل Java على العمل بشكل جيد في الشبكات من خلال تمكين المكتبات للتسلسل والتجميع وتنسيقات البيانات المتنوعة. اللغات التي لا تحتوي على انعكاس مثل C مطلوبة لاستخدام المترجمين المساعدين لمهام مثل تدوين بناء الجملة المجردة لإنتاج كود للتسلسل والتجميع.

يمكن استخدام الانعكاس لمراقبة وتعديل تنفيذ البرنامج في وقت التشغيل . يمكن لمكون البرنامج الموجه نحو الانعكاس مراقبة تنفيذ مجموعة من التعليمات البرمجية ويمكنه تعديل نفسه وفقًا للهدف المطلوب من هذه المجموعة. يتم تحقيق ذلك عادةً عن طريق تعيين تعليمات برمجية ديناميكيًا في وقت التشغيل.

في لغات البرمجة الموجهة للكائنات مثل Java ، يسمح الانعكاس بفحص الفئات والواجهات والحقول والطرق في وقت التشغيل دون معرفة أسماء الواجهات والحقول والطرق في وقت التجميع . كما يسمح بإنشاء كائنات جديدة واستدعاء الطرق.

غالبًا ما يتم استخدام الانعكاس كجزء من اختبار البرمجيات ، مثل إنشاء/إنشاء مثيلات وقت التشغيل للأشياء الوهمية .

ويعتبر التأمل أيضًا استراتيجية أساسية للبرمجة الفوقية .

في بعض لغات البرمجة الموجهة للكائنات مثل C# و Java ، يمكن استخدام الانعكاس لتجاوز قواعد إمكانية وصول الأعضاء . بالنسبة لخصائص C#، يمكن تحقيق ذلك من خلال الكتابة مباشرة على الحقل الداعم (غير المرئي عادةً) لخاصية غير عامة. من الممكن أيضًا العثور على طرق غير عامة للفئات والأنواع واستدعائها يدويًا. يعمل هذا مع الملفات الداخلية للمشروع وكذلك المكتبات الخارجية مثل تجميعات .NET وأرشيفات Java.

تطبيق

توفر اللغة التي تدعم الانعكاس عددًا من الميزات المتاحة في وقت التشغيل والتي قد يكون من الصعب تحقيقها في لغة ذات مستوى أدنى. بعض هذه الميزات هي القدرة على:

يمكن تنفيذ هذه الميزات بطرق مختلفة. في MOO ، يشكل الانعكاس جزءًا طبيعيًا من لغة البرمجة اليومية. عندما يتم استدعاء الأفعال (الطرق)، يتم ملء متغيرات مختلفة مثل verb (اسم الفعل الذي يتم استدعاؤه) و this (الكائن الذي يتم استدعاء الفعل عليه) لإعطاء سياق الاستدعاء. تتم إدارة الأمان عادةً عن طريق الوصول إلى مكدس المتصل برمجيًا: نظرًا لأن callers () عبارة عن قائمة بالطرق التي تم بها استدعاء الفعل الحالي في النهاية، فإن إجراء اختبارات على callers () [0] (الأمر الذي استدعاه المستخدم الأصلي) يسمح للفعل بحماية نفسه من الاستخدام غير المصرح به.

تعتمد اللغات المترجمة على نظام وقت التشغيل الخاص بها لتوفير معلومات حول الكود المصدر. على سبيل المثال، يسجل ملف Objective-C القابل للتنفيذ المترجم أسماء جميع الطرق في كتلة من الملف القابل للتنفيذ، مما يوفر جدولاً لمطابقة هذه الطرق مع الطرق الأساسية (أو محددات هذه الطرق) المترجمة في البرنامج. في لغة مترجمة تدعم إنشاء الوظائف وقت التشغيل، مثل Common Lisp ، يجب أن تتضمن بيئة وقت التشغيل مُجمِّعًا أو مُفسِّرًا.

يمكن تنفيذ الانعكاس للغات التي لا تحتوي على انعكاس مدمج باستخدام نظام تحويل البرنامج لتحديد تغييرات الكود المصدر التلقائية.

اعتبارات أمنية

قد يسمح الانعكاس للمستخدم بإنشاء مسارات تدفق تحكم غير متوقعة عبر تطبيق، مما قد يؤدي إلى تجاوز تدابير الأمان. وقد يستغل المهاجمون ذلك. [4] سمحت الثغرات التاريخية في Java الناجمة عن الانعكاس غير الآمن للكود المسترد من أجهزة بعيدة غير موثوقة بالخروج من آلية أمان Java sandbox . خلصت دراسة واسعة النطاق لـ 120 ثغرة أمنية في Java في عام 2013 إلى أن الانعكاس غير الآمن هو الثغرة الأمنية الأكثر شيوعًا في Java، على الرغم من أنها ليست الأكثر استغلالًا. [5]

أمثلة

تنشئ مقتطفات التعليمات البرمجية التالية مثيلًا foo للفئة وتستدعي طريقتها . لكل لغة برمجة ، يتم عرض تسلسلات الاستدعاء القائمة على الوضع الطبيعي والانعكاس. Foo PrintHello

اللغة الشائعة

فيما يلي مثال في Common Lisp باستخدام نظام كائنات Common Lisp :

( defclass foo () ()) ( defmethod print-hello (( f foo )) ( format T "Hello from ~S~%" f ))   
       

;; عادي، بدون انعكاس 
( let (( foo ( make-instance 'foo ))) ( print-hello foo ))   
   

;; مع الانعكاس للبحث عن الفصل المسمى "foo" والطريقة 
المسمى "print-hello" المتخصصة في "foo". 
( let* (( foo-class ( find-class ( read-from-string "foo" ))) ( print-hello-method ( find-method ( symbol-function ( read-from-string "print-hello" )) nil ( list foo-class )))) ( funcall ( sb-mop:method-generic-function print-hello-method ) ( make-instance foo-class )))    
           
                                          
    
            

سي شارب

فيما يلي مثال في C# :

// بدون انعكاس 
var foo = new Foo (); foo . PrintHello ();    


// مع الانعكاس 
Object foo = Activator . CreateInstance ( "complete.classpath.and.Foo" ); MethodInfo method = foo . GetType (). GetMethod ( "PrintHello" ); method . Invoke ( foo , null );   
   
 

دلفي، أوبجيكت باسكال

يفترض مثال Delphi و Object Pascal هذا أنه تم إعلان فئة TFoo في وحدة تسمى Unit1 :

يستخدم RTTI ، Unit1 ؛  

إجراء WithoutReflection ؛ var Foo : TFoo ؛ begin Foo := TFoo . إنشاء ؛ جرب Foo . مرحبًا ؛ أخيرًا Foo . مجاني ؛ نهاية ؛ نهاية ؛ 

   

    
  
    
  
    
  


الإجراء 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:

// بدون انعكاس 
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 );    
   
     
  

يذهب

فيما يلي مثال في Go :

استيراد "انعكاس" 

// بدون انعكاس 
f := Foo {} f . Hello ()  


// مع الانعكاس 
fT := reflect . TypeOf ( Foo {}) fV := reflect . New ( fT )  
  

m := fV . MethodByName ( "Hello" ) if m . IsValid () { m . Call ( nil ) }  
  
    

جافا

وفيما يلي مثال في Java :

استيراد java.lang.reflect.Method ؛ 

// بدون انعكاس 
Foo foo = new Foo (); foo . hello ();    


// مع الانعكاس 
حاول { Object foo = Foo . class . getDeclaredConstructor (). newInstance (); 
       

    الطريقة m = foo.getClass ( ) . getDeclaredMethod ( "hello" ، فئة جديدة < ?>[ 0 ] ); m.invoke ( foo ); } catch ( تجاهل استثناء ReflectiveOperationException ) { }     
    
    

جافا سكريبت

وفيما يلي مثال في JavaScript :

// بدون انعكاس 
const foo = new Foo () foo . hello ()    



// مع الانعكاس const foo = Reflect.struct ( Foo ) const hello = Reflect.get ( foo , ' hello ' ) Reflect.apply ( hello , foo , [ ] )   
    
  

// مع eval eval 
( ' new Foo().hello()' )

جوليا

وفيما يلي مثال في جوليا :

جوليا> نقطة البنية x :: Int y النهاية  
           
           
       

# التفتيش مع الانعكاس 
julia> fieldnames ( Point ) (:x, :y) 


julia> أنواع الحقول ( نقطة ) (Int64، أي) 


جوليا> ص = النقطة ( 3 ، 4 )   

# الوصول باستخدام الانعكاس 
julia> getfield ( p , :x ) 3  

Objective-C

فيما يلي مثال في Objective-C ، مما يعني استخدام إطار عمل OpenStep أو Foundation Kit :

// فئة Foo. 
@interface  Foo  : NSObject 
-  ( void ) hello ؛ 
@end

// إرسال "hello" إلى مثيل Foo بدون انعكاس. 
Foo * obj = [[ Foo alloc ] init ]; [ obj hello ];     
 

// إرسال "hello" إلى مثيل Foo باستخدام الانعكاس. 
id obj = [[ NSClassFromString ( @"Foo" ) alloc ] init ]; [ obj performSelector : @selector ( hello )];     
  

بيرل

وفيما يلي مثال في Perl :

# بدون انعكاس 
$ foo = Foo -> جديد ؛ $foo -> مرحبًا ؛   


# أو 
Foo -> جديد -> مرحبًا ؛

# مع الانعكاس 
my $class = "Foo" my $constructor = "new" ; my $method = "hello" ;   
   
   

$f الخاص بي = $class -> $constructor ؛ $f -> $method ؛   


# أو 
$class -> $constructor -> $method ؛

# مع تقييم 
" جديد Foo->hello؛" ; 

بي اتش بي

فيما يلي مثال في PHP : [6]

// بدون انعكاس 
$foo  =  new  Foo (); 
$foo -> hello ();

// مع الانعكاس، باستخدام واجهة برمجة التطبيقات Reflections 
$reflector  =  new  ReflectionClass ( "Foo" ); 
$foo  =  $reflector -> newInstance (); 
$hello  =  $reflector -> getMethod ( "hello" ); 
$hello -> invoke ( $foo );

بايثون

وفيما يلي مثال في بايثون :

# بدون انعكاس 
obj  =  Foo () 
obj . hello ()

# مع الانعكاس 
obj  =  globals ()[ "Foo" ]() 
getattr ( obj ,  "hello" )()

# مع eval eval 
( " Foo().hello()" )

ر

وفيما يلي مثال في R :

# بدون انعكاس، بافتراض أن foo() ترجع كائنًا من نوع S3 يحتوي على طريقة "hello" 
obj <- foo () hello ( obj )  


# مع انعكاس 
class_name <- "foo" generic_having_foo_method <- "hello" obj <- do.call ( class_name , list ()) do.call ( generic_having_foo_method , alist ( obj ))  
  
   
 

روبي

وفيما يلي مثال في Ruby :

# بدون انعكاس 
obj = Foo . new obj . hello  


# مع الانعكاس 
obj = Object . const_get ( "Foo" ) . new obj . send :hello  
 

# مع التقييم 
" Foo.new.hello" 

شوجو

فيما يلي مثال لاستخدام Xojo :

'بدون انعكاس 
Dim fooInstance As New Foo fooInstance . PrintHello    


'مع الانعكاس 
Dim classInfo As Introspection . Typeinfo = GetTypeInfo ( Foo ) Dim buildors () As Introspection . ConstructorInfo = classInfo . GetConstructors Dim fooInstance As Foo = buildors ( 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     
     
     
     
      
      
    
   

انظر أيضا

مراجع

الاستشهادات

  1. ^ دليل تعليمي حول التأمل السلوكي وتطبيقه بواسطة جاك مالينفانت وآخرون. (PDF) ، غير معروف، محفوظ من الأصل (PDF) في 21 أغسطس 2017 ، تم استرجاعه في 23 يونيو 2019
  2. ^ بريان كانتويل سميث، التأمل الإجرائي في لغات البرمجة، قسم الهندسة الكهربائية وعلوم الكمبيوتر، معهد ماساتشوستس للتكنولوجيا، أطروحة دكتوراه، 1982.
  3. ^ Brian C. Smith. Reflection and semantics in a procedural language Archived 2015-12-13 at the Wayback Machine . التقرير الفني MIT-LCS-TR-272، معهد ماساتشوستس للتكنولوجيا، كامبريدج، ماساتشوستس، يناير 1982.
  4. ^ باروس، باولو؛ جاست، رينيه؛ ميلشتاين، سوزان؛ فينز، بول؛ ديتل، فيرنر؛ داموريم، مارسيلو؛ إيرنست، مايكل د. (أغسطس 2015). التحليل الثابت لتدفق التحكم الضمني: حل انعكاس جافا ونوايا أندرويد (PDF) (تقرير). جامعة واشنطن. UW-CSE-15-08-01 . تم الاسترجاع في 7 أكتوبر 2021 .
  5. ^ Eauvidoum, Ieu; disk noise (5 أكتوبر 2021). "عشرون عامًا من الهروب من بيئة Java Sandbox". Phrack . المجلد 10، العدد 46. تم الاسترجاع في 7 أكتوبر 2021 .
  6. ^ "PHP: ReflectionClass - Manual". www.php.net .

مصادر

  • جوناثان م. سوبل ودانيال ب. فريدمان. مقدمة إلى البرمجة الموجهة نحو التأمل (1996)، جامعة إنديانا .
  • تقنية مكافحة الانعكاس باستخدام C# وC++/CLI wrapper لمنع سارق الكود

قراءة إضافية

  • إيرا ر. فورمان ونيت فورمان، انعكاس جافا في العمل (2005)، ISBN 1-932394-18-4 
  • إيرا ر. فورمان وسكوت دانفورث، وضع الفئات الفوقية في العمل (1999)، ISBN 0-201-43305-2 
  • التأمل في البرمجة المنطقية والوظيفية والبرمجة الموجهة للكائنات: دراسة مقارنة قصيرة
  • مقدمة إلى البرمجة الموجهة نحو التأمل
  • صفحات بريان فوت عن التأمل في Smalltalk
  • برنامج تعليمي حول Java Reflection API من Oracle

انظر أيضا

  • {{ لغة الحاسوب }}
  • {{ لغات البرمجة }}
  • {{ مربع التنقل الخاص بأنماط البرمجة }}
تم الاسترجاع من "https://en.wikipedia.org/w/index.php?title=البرمجة_الانعكاسية&oldid=1244644514"
Original text
Rate this translation
Your feedback will be used to help improve Google Translate