반사 프로그래밍

Reflective programming

컴퓨터 과학에서, 반사 프로그래밍 또는 반사는 자신의 구조와 [1]행동을 조사하고, 성찰하고, 수정하는 프로세스의 능력입니다.

이력

최초의 컴퓨터는 본래 반사적인 원어민 어셈블리 언어로 프로그래밍되었습니다.이러한 원래의 아키텍처는 명령을 데이터로 정의하고 자체 수정 코드를 사용하여 프로그래밍할 수 있었기 때문입니다.프로그래밍의 대부분이 Algol, Cobol, Fortran, Pascal, C와 같은 상위 컴파일 언어로 이동함에 따라, 이러한 반사 능력은 유형 시스템에 반영이 내장된 새로운 프로그래밍 언어가 [citation needed]등장하기 전까지 거의 사라졌다.

Brian Cantwell Smith의 1982년 박사학위 논문은 절차 프로그래밍 언어에서의 계산적 반영의 개념[2][3]3-Lisp의 구성요소로서의 메타 순환 해석기의 개념을 도입했습니다.

사용하다

리플렉션(reflection)은 프로그래머가 데이터를 표시하기 위한 범용 소프트웨어 라이브러리를 만들고, 다양한 형식의 데이터를 처리하며, 통신을 위한 데이터의 직렬화 또는 역직렬화를 수행하거나, 컨테이너 또는 통신 버스트의 데이터 번들 및 분리를 수행할 수 있도록 지원합니다.

반성을 효과적으로 사용하려면 거의 항상 계획이 필요합니다. 설계 프레임워크, 인코딩 기술, 객체 라이브러리, 데이터베이스 또는 엔티티 관계 맵입니다.

리플렉션은 언어를 네트워크 지향 코드에 더 적합하게 만듭니다.예를 들어, Java와 같은 언어가 네트워크에서 원활하게 작동하도록 지원하며, 라이브러리를 통해 직렬화, 번들링 및 다양한 데이터 형식을 사용할 수 있습니다.C와 같이 반영되지 않는 언어는 Abstract Syntax Notation 의 태스크에 보조 컴파일러를 사용하여 시리얼라이제이션 및 번들용 코드를 생성해야 합니다.

리플렉션은 실행 시 프로그램 실행을 관찰하고 수정하는 데 사용할 수 있습니다.리플렉션 지향 프로그램 컴포넌트는 코드 인클로저의 실행을 감시할 수 있으며 그 인클로저의 바람직한 목표에 따라 자신을 변경할 수 있다.이는 일반적으로 실행 시 프로그램 코드를 동적으로 할당함으로써 이루어집니다.

Java와 같은 객체 지향 프로그래밍 언어에서 리플렉션은 컴파일인터페이스, 필드, 메서드의 이름을 몰라도 실행 시 클래스, 인터페이스, 필드 및 메서드를 검사할 수 있습니다.또한 새 객체의 인스턴스화와 메서드의 호출도 허용합니다.

리플렉션(reflection)은 모의 객체의 런타임 생성/인스턴스화 등 소프트웨어 테스트의 일부로 자주 사용됩니다.

성찰은 메타프로그래밍의 핵심 전략이기도 합니다.

C#Java같은 일부 객체 지향 프로그래밍 언어에서는 리플렉션을 사용하여 구성원 접근성 규칙을 우회할 수 있습니다.C# 속성의 경우 비공개 속성의 (보통 보이지 않는) backing 필드에 직접 쓰는 것으로 이를 실현할 수 있습니다.공개되지 않은 클래스 및 유형의 메서드를 찾아 수동으로 호출할 수도 있습니다.이는 프로젝트 내부 파일 및 등의 외부 라이브러리에 적용됩니다.NET의 어셈블리 및 Java의 아카이브.

실행

언어를 지원하는 리플렉션은 실행 시 낮은 수준의 언어에서는 달성하기 어려운 많은 기능을 제공합니다.이러한 기능에는 다음과 같은 것이 있습니다.

  • 런타임에 소스 코드 구성(코드 블록, 클래스, 메서드, 프로토콜 등)을 검색수정합니다.
  • 클래스 또는 함수의 심볼 이름과 일치하는 문자열을 해당 클래스 또는 함수에 대한 참조 또는 호출로 변환합니다.
  • 실행 시 소스 코드 문인 것처럼 문자열을 평가합니다.
  • 언어의 바이트 코드에 대한 새 인터프리터를 생성하여 프로그래밍 구성에 새로운 의미 또는 목적을 부여합니다.

이러한 기능은 다양한 방법으로 구현할 수 있습니다.MO에서 리플리테이션은 일상적인 프로그래밍 숙어의 자연스러운 부분을 형성합니다.동사(방법)가 호출되면 호출되는 동사(호출되는 동사의 이름) 및 (호출되는 동사의 객체)와 같은 다양한 변수가 입력되어 호출의 컨텍스트를 제공합니다.일반적으로 보안은 발신자 스택에 프로그래밍 방식으로 액세스함으로써 관리됩니다.callers()는 현재 동사가 최종적으로 호출된 메서드의 목록이기 때문에 callers()[0](원사용자가 호출한 명령어)에 대해 테스트를 실행하면 동사가 부정사용으로부터 자신을 보호할 수 있습니다.

컴파일된 언어는 런타임 시스템을 사용하여 소스 코드에 대한 정보를 제공합니다.예를 들어 컴파일된 Objective-C 실행파일은 실행파일의 블록에 모든 메서드의 이름을 기록하고 프로그램에 컴파일된 기본 메서드(또는 이들 메서드의 셀렉터)와 대응하는 테이블을 제공합니다.Common Lisp와 같은 함수의 런타임 생성을 지원하는 컴파일 언어에서는 런타임 환경에 컴파일러 또는 인터프리터가 포함되어야 합니다.

프로그램 변환 시스템을 사용하여 자동화된 소스 코드 변경을 정의함으로써 내장된 반영이 없는 언어에 대해 반영을 구현할 수 있습니다.

보안에 관한 고려 사항

리플렉션을 통해 사용자가 애플리케이션을 통해 예기치 않은 제어 흐름 경로를 생성하여 보안 조치를 무시할 수 있습니다.공격자가 [4]이 취약성을 이용할 수 있습니다.안전하지 않은 반사로 인한 Java의 과거 취약성으로 인해 신뢰할 수 없는 원격 시스템에서 검색된 코드가 Java 샌드박스 보안 메커니즘에서 분리될 수 있습니다.2013년 120개의 Java 취약성에 대한 대규모 연구에서 안전하지 않은 반사가 Java에서 가장 일반적인 취약점이라고 결론지었지만 가장 많이 [5]악용되지는 않았습니다.

다음 코드 스니펫은 인스턴스를 만듭니다. foo계급의 Foo그리고 그 방법을 호출한다. PrintHello프로그래밍 언어에 대해 일반 콜시퀀스와 리플렉션베이스 콜시퀀스가 표시됩니다.

C#

다음으로 C#의 예를 나타냅니다.

// 반사 없음 푸우 후우 = 신규 푸우(); 후우.Print Hello();  //반사 포함 물건 후우 = 액티베이터.Create Instance(complete.classpath.그리고후우); 메서드 정보 방법 = 후우.Get Type (Get Type)().Get Method(메서드라이브("Print Hello"); 방법.호출하다(후우, 무효); 

델파이 / 오브젝트 파스칼

Delphi/Object Pascal의 예에서는 다음과 같이 가정합니다.TFoo 클래스는 Unit1이라는 유닛으로 선언되었습니다.

사용하다 Retti, 유닛 1;  절차. 리플렉션; 변화하다   푸우: TFoo; 시작한다.   푸우 := TFoo.만들다;   해라     푸우.안녕;   마침내.     푸우.공짜;   끝.; 끝.;  절차. 리플렉션 포함; 변화하다   Retti Context: TRTI 콘텍스트;   Rtti Type(Retti Type): TRTi Instance Type;   푸우: 토브젝트; 시작한다.   Rtti Type(Retti Type) := Retti Context.검색 유형('유닛 1.TFOO') ~하듯이 TRTi Instance Type;   푸우 := Rtti Type(Retti Type).Get Method(메서드라이브('작성').호출하다(Rtti Type(Retti Type).메타클래스유형, []).As Object (As Object(개체);   해라     Rtti Type(Retti Type).Get Method(메서드라이브('안녕하세요').호출하다(푸우, []);   마침내.     푸우.공짜;   끝.; 끝.; 

eC

다음은 eC의 예입니다.

// 반사 없음 푸우 후우 { }; 후우.안녕();  //반사 포함 학급 foo 클래스 = eSystem_Find Class(__이 모듈, "푸"); 사례 후우 = e인스턴스_신규(foo 클래스); 방법 m = eClass_Find Method(foo 클래스, "안녕하세요", foo 클래스.모듈); ((무효 (*)())(무효 *)m.기능.)(후우); 

가세요

다음은 Go의 입니다.

수입품 '반영'  // 반사 없음 f := 푸우{} f.안녕()  //반사 포함 fT := 비추다.종류(푸우{}) fV := 비추다.신규(fT)  m := fV.Method By Name(메서드 바이 네임("안녕하세요") 한다면 m.유효.() {     m.불러(제로) } 

자바

Java의 를 다음에 나타냅니다.

수입품 java.displect.reflect.방법;  // 반사 없음 푸우 후우 = 신규 푸우(); 후우.안녕();  //반사 포함 해라 {     물건 후우 = 푸우.학급.getDeclaredConstructor().newInstance();      방법 m = 후우.클래스 취득().getDeclared 메서드("안녕하세요", 신규 학급<?>[0]);     m.호출하다(후우); } 또 만나 (리플렉티브 오퍼레이션예외. 무시당했다) {} 

자바스크립트

다음은 JavaScript의 예입니다.

// 반사 없음 컨스턴트 후우 = 신규 푸우() 후우.안녕()  //반사 포함 컨스턴트 후우 = 비추다.건설하다(푸우) 컨스턴트 안녕 = 비추다.얻다(후우, '안녕하세요') 비추다.적용합니다.(안녕, 후우, [])  // 평가 포함 평가하다('new Foo().hello()') 

줄리아.

다음은 Julia(프로그래밍 언어)입니다.

줄리아> 구조 포인트            x::내부            y        끝.  # 반사가 있는 점검 줄리아> 필드명(포인트) (:x,:y)  줄리아> 필드 타입(포인트) (Int64, 임의)  줄리아> p = 포인트(3,4)  # 리플렉션 포함 접근 줄리아> 취득 필드(p, :x) 3 

목표-C

다음은 OpenStep 또는 Foundation Kit 프레임워크 중 하나를 사용하는 Objective-C의 예입니다.

// Foo 클래스@interface Foo : NSObject - (void)hello; @end // 반영 없이 Foo 인스턴스에 "hello"보냅니다.Foo *obj = [ Foo allocate ]init;[obj hello]; //반사가 포함된 Foo 인스턴스에 "hello"를 보냅니다.id obj = [NSClassFromString(@"Foo") allocate init];[obj perform Selector: @selector(hello)]; 

Perl의 예를 다음에 나타냅니다.

# 반성 없음 나의 $foo = 푸우->신규; $foo->안녕;  # 또는 푸우->신규->안녕;  # 성찰과 함께 나의 $클래스 = "푸" 나의 1달러 또는 1달러 = "신규"; 나의 $140 = "안녕하세요";  나의 f달러 = $클래스->1달러 또는 1달러; f달러->$140;  # 또는 $클래스->1달러 또는 1달러->$140;  # 평가판 포함 평가하다 "새로운 Foo->안녕하세요"; 

PHP

다음은 PHP의 입니다.

// 반사 없음 $foo = 신규 푸우(); $foo->안녕();  // Reflection 포함, Reflections API 사용 $140 = 신규 반사 클래스('푸우'); $foo = $140->newInstance(); $hello = $140->get Method(방법)('안녕하세요'); $hello->호출하다($foo); 

파이썬

다음은 Python의 입니다.

# 반성 없음 obj = 푸우() obj.안녕()  # 성찰과 함께 obj = 글로벌()["푸"]() 취득하다(obj, "안녕하세요")()  # 평가판 포함 평가하다("Foo().hello()") 

R

R의 예를 다음에 나타냅니다.

# 리플렉션 없이 foo()가 메서드 "hello"를 가진 S3형 객체를 반환한다고 가정합니다. obj <-> 후우() 안녕(obj)  # 성찰과 함께 class_name <-> "푸" generic_having_foo_displays <-> "안녕하세요" obj <-> do.call을 실행하다(class_name, 목록.()) do.call을 실행하다(generic_having_foo_displays, 리스트(obj)) 

루비

다음은 Ruby의 입니다.

# 반성 없음 obj = 푸우.신규 obj.안녕  # 성찰과 함께 class_name = "푸" method_name = : 안녕하세요 obj = 물건.const_get(class_name).신규 obj.보내세요 method_name  # 평가판 포함 평가하다 "신규 푸우.안녕하세요. 

조조

다음은 Xojo를 사용하는 예입니다.

'반성 없음 어둡다 foo Instance(인스턴스) ~하듯이 신규 푸우 foo Instance(인스턴스).Print Hello  '반성 포함 어둡다 클래스 정보 ~하듯이 자기성찰.유형 정보 = GetTypeInfo(푸우) 어둡다 컨스트럭터() ~하듯이 자기성찰.컨스트럭터정보 = 클래스 정보.GetConstructors 어둡다 foo Instance(인스턴스) ~하듯이 푸우 = 컨스트럭터(0).호출하다 어둡다 방법들() ~하듯이 자기성찰.메서드 정보 = 클래스 정보.Get Methods (Get Methods) 위해서 각각 m ~하듯이 자기성찰.메서드 정보  방법들   한다면 m.이름. = "Print Hello" 그리고나서     m.호출하다(foo Instance(인스턴스))   끝. 한다면 다음 분. 

「 」를 참조해 주세요.

레퍼런스

인용문

  1. ^ 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
  2. ^ Brian Cantwell Smith, Massachusetts Institute of Technology, 전기공학 및 컴퓨터과학부 프로그래밍 언어 절차적 반영, 박사학위 논문, 1982.
  3. ^ 브라이언 C.Smith. 절차 언어반영 의미론 2015-12-13 웨이백 머신에 보관.기술 보고서 MIT-LCS-TR-272, Massachusetts Institute of Technology, Massachusetts, Cambridge, Massachusetts, 1982년 1월
  4. ^ Barros, Paulo; Just, René; Millstein, Suzanne; Vines, Paul; Dietl, Werner; d'Amorim, Marcelo; Ernst, Michael D. (August 2015). Static Analysis of Implicit Control Flow: Resolving Java Reflection and Android Intents (PDF) (Report). University of Washington. UW-CSE-15-08-01. Retrieved October 7, 2021.
  5. ^ Eauvidoum, Ieu; disk noise (October 5, 2021). "Twenty years of Escaping the Java Sandbox". Phrack. Vol. 10, no. 46. Retrieved October 7, 2021.{{cite magazine}}: CS1 maint: 작성자 파라미터 사용(링크)

원천

추가 정보

외부 링크