흥미로운 질문 - 이름 변경 리팩터링의 특정 사례에 대해이 회귀 전략에서 얻을 수있는 확실한 "예"대답을 좋아합니다.
나는 당신이 (eval
같은 것없이, 또는 적어도 일부) 루비를 컴파일 할 수 있는지 여부를 알 수있을만큼 전문가 모르겠지만에서 몇 가지 힌트가있을 것 같다 :
완전한 편집이 불가능하다고 가정하면 추상 해석 방법은 어떻게됩니까? 루비를 AST로 파싱하고 AST에서 C 코드를 내 보낸 다음 C 코드를 컴파일 할 수 있습니다. C 코드는 루비 코드의 동작을 완전히 캡처 할 필요가 없습니다. 루비가 뚜렷 할 때마다 컴파일 가능해야하고 뚜렷하게 구별되어야합니다. (실제 실행하면 횡설수설하거나, 즉각적인 메모리 위반 오류가 발생할 수 있습니다.)
간단한 예로, 루비가 지원하는 곱셈과 C는 가정하지 않았습니다. 그런 다음 당신은 당신의 C 코드에서 정적 mult
기능을 포함하고 번역 할 수 있습니다 : 이름 리팩토링에서 불변 것 그러나 변화의 다른 종류에 따라 차이를 보여 것 a = b + c*d
a = b + mult(c,d)
및 결과 컴파일 된 코드. mult
기능은 실제로 당신이 대신 중 하나를 가질 수 곱셈을 구현할 필요가 없다 :
static int mult(int a, int b) { return a + b; } // pretty close
static int mult(int a, int b) { return *0; } // not close at all, but still sufficient
당신은 여전히 C 컴파일러는 정의를 인라인하지 않을 당신이 오랫동안 필요로하는 불변성을 얻을 것입니다. 호환되지 않는 루비 구조에서 덜 기능적이지만 별개의 C 구조체와 같은 종류의 변환은 클래스 조작을 C 구조 참조로 매핑하여 객체 조작 등을 위해 작동해야합니다. 요점은 실제 동작을 희생하면서 명명 관계를 그대로 유지하려는 것입니다.
가 (난 당신이 루비 코드의 모든 클래스와 특성 이름의 이름을 따서 명명 동일한 구조체 유형에 구성원 (모든 포인터를 갖는 단일 C 구조체)와 함께 뭔가를 할 수 있는지 궁금합니다. 클래스와 객체 작업은 다음에 해당하는 것 이 단일 구조를 사용하여 중첩 된 참조 해제 작업.)
정밀한 매핑을 공식화 할 수 없더라도 일부 사소한 차이가 누락 된 부정확 한 매핑으로 인해 원래 이름 리팩토링에 대한 확신을 늘릴 수 있습니다.
이러한 스키마를 구현하는 가장 빠른 방법은 바이트 코드에서 C로 (루비 AST에서 C로 매핑하는 것) 일 수 있습니다. 이렇게하면 파싱을 많이 줄일 수 있지만 매핑을 이해하고 확인하는 것이 더 어려울 것입니다.
테스트 결과 아무것도 없습니다. – DGM
사실, .exe를 비교해도 똑같은지 알 수는 없으며 테스트 적용 범위를 신뢰하기보다는 다른 점이 없음을 보장합니다. 필자는 테스트 작성에 확고한 신봉자이지만 간단한 테스트 리팩터링을 사용하여 불량 테스트 범위가있는 거대한 레거시 앱을 만들 수 있기를 바란다. 그리고 내 방식은 훨씬 더 빠르고 정확한 변경을 포착 할 수있다. 그게 내 질문의 핵심이야. –