2012-09-01 1 views
2

C에서는 실행 파일을 생성하고 리팩토링 만하는 리팩토링을 수행 한 다음 실행 파일을 다시 비교하여 실행 파일이 변경되지 않았 음을 확인합니다. 리팩토링자가 아무 것도 깨지 않았는지 확인하십시오리팩토링 전후의 Rails의 실행 파일 비교 방법

누구나 루비, 특히 레일즈 앱과 비슷한 일을 한 적이 있습니까? 전략과 방법이 좋을 것입니다. 이상적으로는, 나는 어떤 종류의 하나의 파일을 출력하는 스크립트를 실행할 수 있습니다. 순수 바이트 코드로 변경되지 않았으며 이름을 변경하여 변경되지 않았습니다. JRuby 또는 Rubinus가 도움이 될 것으로 추측합니다.

답변

2

이 전략은 Ruby에서 작동하지 않을 것이라고 생각합니다. 네가 루비에서 이름을 짓는 이름의 대부분은 그 이름을 가지고있다. 여기에는 클래스, 모듈, 상수 및 인스턴스 변수가 포함됩니다.

자동화 된 단위 및 통합 테스트는 루비 리팩토링을 지원하기 위해 이동하는 방법입니다.

+0

테스트 결과 아무것도 없습니다. – DGM

+0

사실, .exe를 비교해도 똑같은지 알 수는 없으며 테스트 적용 범위를 신뢰하기보다는 다른 점이 없음을 보장합니다. 필자는 테스트 작성에 확고한 신봉자이지만 간단한 테스트 리팩터링을 사용하여 불량 테스트 범위가있는 거대한 레거시 앱을 만들 수 있기를 바란다. 그리고 내 방식은 훨씬 더 빠르고 정확한 변경을 포착 할 수있다. 그게 내 질문의 핵심이야. –

2

흥미로운 질문 - 이름 변경 리팩터링의 특정 사례에 대해이 회귀 전략에서 얻을 수있는 확실한 "예"대답을 좋아합니다.

나는 당신이 (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로 매핑하는 것) 일 수 있습니다. 이렇게하면 파싱을 많이 줄일 수 있지만 매핑을 이해하고 확인하는 것이 더 어려울 것입니다.