본문 바로가기
Homo Coding

세가지 공공의 적들 : 잘라내기(Cut), 복사(Copy), 붙여넣기(Paste)

by javauser 2008. 3. 14.

복사(copy)-붙여넣기(paste)는 삶을 더 편하기 만드는 것처럼 보이지만, 종종 불일치성을 유발시킨다. 사용자에게 복사된 대상들 사이의 의미론적인 관계를 지정하게끔 하는 자유를 부여하는 것은 이러한 "범죄"를 교정하는데 도움이 될 수 있다.

많은 소프트웨어 개발자들은 코드가 계속해서 이어지는 곳에서 일치하지 않게 되었던 copy-paste된 코드의 부분으로부터 에러가 기인되었다는 것을 잠못 이룬 밤을 지세운 후 발견할 수 있어야만 되는 절망적인 프로그램 디버깅의 감정을 알고 있다. 더 안좋은 것은 더 많은 그러한 보이지 않는 에러가 발견되기를 기다리고 있다는 좌절감이다.
복사한 코드로부터 발생되는 문제는 새로운 것이 아니며, 많은 연구자들은 어떻게 자동으로 복사된 코드 부분을 찾을 수 있는지를 조사해왔다. 자주 권고되는 방법은 복사한 코드를 리팩토링하는 것이다. - 해당 부분을 함수, 매크로, 혹은 클래스와 같은 의미있는 프로그래밍 언어의 추상화로 일반화시키고 해당 부분이 발생하는 지점을 그러한 추상화에 대한 참조로 대체하는 것이다. 하지만, 리팩토링은 항상 선택할 수 있는 방법이 아니며 동일한 copy-paste 결함으로 고통받는 다른 종류의 텍스트 에디팅에 대한 해결책은 분명하게 아니다.
copy-paste 행위가 광범위하게 사용되고 불일치성을 유발시키는 경향이 있는 상태에서 현재 에디터 프로그램을 다시 생각할 강력한 필요성이 명백하게 존재한다. 한가지 해결책은 잘라내기(cut), 복사(copy), 붙여넣기(paste)를 이러한 사용 이면에 의도된 의미로 직접적으로 대응되는 행위로 대체하는 것이다. 이러한 행위를 사용해서 사용자는 복사한 대상들 사이의 의미론적인 관계를 부여할 수 있으며, 에디터 프로그램은 그러한 관계에 대한 긴 시간 지원으로 도움이 되는 해당 정보를 사용할 수 있다. 따라서 잘라내기(cut), 복사(copy), 붙여넣기(paste) 사용으로 현재 발생되는 불일치성을 피할 수 있을 것이다.

사용 시나리오
왜 잘라내기(cut), 복사(copy), 붙여넣기(paste) 가 에러를 유발시킬 수 있는지를 이해하기 위해서 왜 사람들이 이러한 행위를 사용하는지를 정확하게 살펴보는 것이 도움이 된다. 전형적인 5가지 시나리오가 있으며, 이들 중 어떤 것은 불일치성을 만들게 된다.
삭제를 위한 잘라내기(cut). 비록 이러한 행위는 행위 유발자가 잘라내기(cut) 기능으로 의도한 것이 아니지만, - 그리고 대부분의 프로그램들은 실제로 별도의 삭제 기능을 가진다 - 그럼에도 불구하고 가능하다. 하지만, 이러한 사용은 불일치성을 유발시키지는 않으며, 따라서 이러한 시나리오는 비교적 해가 없다.
어떤 내용을 옮기기 위한 잘라내기(cut)와 붙여넣기(paste). 마찬가지로 불일치성에 대한 잠재성은 없으며, 이는 어떤 내용은 한 장소에서 다른 곳으로 단순히 올기는 것이기 때문이다.
복제를 위한 잘라내기(cut)와 붙여넣기(paste). 이러한 생각은 몇군데에 동일한 것이 정확하게 있다는 것이다. 변수명을 타이핑 하는 것은 이러한 시나리오에 대한 좋은 예이다. 소프트웨어 엔지니어는 i, j, k 보다 더 설명이 가미된 변수명을 사용하도록 배워서, 이들은 myActionListenerForTheUpperRightButton 와 같은 변수를 만들게 될 것이며, 이는 수십번 접근할 필요가 있을 것이다. 가능한 전략은 변수명을 copy and paste하는 것이다.
템플릿을 만들기 위한 복사(copy)와 붙여넣기(paste). 이 경우, 목적은 두개의 유사한 인스턴스를 가진다는 것이다. 이전 시나리오의 예제를 계속해서 사용해보면, 소프트웨어 엔지니어가 myActionListenerForTheUpperRightButton 을 처리하는 코드를 끝마치고, 이제는 myActionListenerForTheUpperRightButton 을 사용해서 동일한 것을 하기를 원한다고 가정하자. 미치지 않기 위해서는 코드를 copy-paste하고 수정할 것이다.
논리적인 연결이 없는 복사(copy)와 붙여넣기(paste). 이 경우에는 원본과 복사본 간의 논리적인 관계가 없다. 예를 들어, 프로그래밍이 자바 클래스이라면, 소프트웨어 엔지니어는 public void를 가지는 몇몇 메소드를 선언하는 것으로 시작할 것이다. 시간을 절약하기 위해 그는 이러한 글자를 한번만 타이핑하고 다른 메소드를 위해 해당 글자를 copy-paste후, public int 와 같이 변경하기를 원할 수도 있다. 이 예제는 논리적인 연결이라는 관점에서 이전 것과 다르다. 이전의 경우에서, 복사된 텍스트는 논리적인 연결고리가 있다. 하지만, 여기서는 그렇지 않다. 만일 소프트웨어 엔지니어가 myActionListenerForTheUpperRightButton 을 처리하는 코드를 변경한다면, 다른 복사본에 대해서 유사한 변경을 일으킬 가능성이 높다. 하지만, 만일 그가 메소드의 접근자를 public 에서 private 로 변경한다면, 동일한 클래스에 있는 다른 메소드의 접근자를 변경할 필요가 통상 없을 것이다. 결론적으로, 이러한 시나리오는 덜 해를 끼친다. - 복사된 텍스트는 일치할 필요가 없으며, 따라서 불일치성 문제의 가능성은 없다.

위의 다섯가지 기본적인 사용 시나리오들은 역시 잘라낸(cut) 다음 몇군데 붙여넣기(paste) 하는 것과 같은 하나 이상의 재미있는 시나리오를 포함하고 있으며, 이는 하나 이상의 복사에 이어지는 실제로 move 행위이다.

왜 문제가 잘못되었는가
불일치성은 세번째와 네번째 사용 시나리오에서 발생한다. 가장 빈도가 높은 문제는 사용자가 어떤 텍스트 복사를 변경하고 다른 것을 변경하는 것을 잊어버리는 것이다. 네번째 사용에서, 복사된 텍스트를 변경하는 것을 잊어보리는 것은 불일치성에 대한 또 다른 가능성을 열어놓을 수 있다.
이는 텍스트들이 계속해서 있는 동안에 몇번이고 변경되어야만 하는 크고 계속 남아있는 텍스트 – 예를 들어, 매뉴얼, 명세, 책, 프로그램 코드 - 에 대해서 특히 더 문제가 된다. 그와 같은 경우, 작성자는 작성자가 내부적으로 일관성을 유지하는 텍스트를 만들기 위해 가했던 추가적인 변경이 무엇인지를 거의 기억하지 못하거나, 원래 작성자가 자리를 떠나고 다른 사람들이 그러한 텍스트들을 그대로 물려받게 된다.
이러한 에러에 대한 최정점에는 키 제약사항이 있다. 즉, 사용자는 복사된 것에 대해 정확한 의미론을 부여할 수 없다. 현재 형태에서, 잘라내기(cut), 복사(copy), 붙여넣기(paste)는 사용자가 텍스트를 복제하는데 도움을 주지만, 이들은 복사된 인스턴스들이 일관성을 유지하는데 보장하는 작업에 도움이 되지 못한다. 이러한 종류의 일을 수행할 수 없다면 컴퓨터를 가지는 점이 무엇인가?

이상적인 프로그램을 향하여

이상적인 에디터 프로그램은 두가지 주요한 기능을 가지게 될 것이다. 첫번째로 클립보드를 사용하지 않게 된다. 클립보드는 텍스트를 복사하는데 단기간 지원만을 제공하고 사용자로 하여금 복사 행위 이면의 의미를 부여할 수 없게 하기 때문에 문제가 된다. 두번째로 전통적인 잘라내기(cut), 복사(copy), 붙여넣기(paste) 기능 대신에 이상적인 프로그램이 이동(move), 동일 복사(copy-identical), 복사 후 변경(copy-and-change), 한번 복사(copy-once)와 같은 사용 시나리오에 대응하는 네가지 기능을 제공하는 것이다.
이동(move) 기능은 사용자가 어떠한 다른 효과없이 한 장소에서 다른 장소로 완전하게 텍스트를 옮기는 것이다. 따라서, 이동(move) 기능은 불일치성을 유발하지 않는다. 이는 현재 잘라내기(cut)와 붙여넣기(paste)를 조합하여 사용하고 있는 것과 대조를 이루는데, 이 경우 텍스트는 클립보드에 남게 되며, 결국 사용자가 불일치성을 유발시킬 수 있는 특별한 위치에 텍스트를 붙여넣을 수 있게 된다.
동일 복사(copy-identical) 기능은 이전에 설명한 세번째 사용 시나리오 – 여러 군데에 정확하게 동일한 것을 가지는 복사 - 에 대응된다. 하지만 동일 복사(copy-identical)는 사용자에게 일치성 보장을 부담하게끔 하지 않는다. 대신에, 동일 복사(copy-identical) 기능 이후에 에디터 프로그램은 복사한 내용이 동일하게 남아있도록 보장할 것이다. 즉, 사용자가 동일 복사(copy-identical) 기능을 사용했을 때 프로그램은 동일하게 남아야 되는 문서가 어느 부분인지를 기억한다. 사용자가 복사한 것을 변경하면, 프로그램은 자동으로 다른 것들도 변경을 한다. 프로그램은 또한 사용자에게 얼마나 많은 다른 복사본이 변경되었는지를 알려주고 다른 복사 부분들을 살펴보도록 하며 저장된 관계를 끊을 수도 있을 것이다.
복사 후 변경(copy-and-change) 기능은 네번째 사용 시나리오 – 텍스트를 복사하고 원래의 것과 동일하지 않고 비슷한 것을 만들기 위해 새로운 것을 변경하는 것 - 와 관련이 있다. 이 경우 프로그램은 원본의 변경이 복제본에 어떻게 적용되는지를 알 수 없기 때문에 예방적이지 못하다. 하지만, 사용자가 복사 후 변경(copy-and-change) 기능을 사용할 때 기억하고 변경이 불일치성을 유발시키는 가능성이 있을 때에 사용자에게 통지할 수 있다.
복제본이 복사 후 변경되지 않고 남아 있는 한, 프로그램은 이를 변경하기를 원했던 사용자에게 적절하게 화면으로 상기시키는 기능을 사용해서 표시해야 한다. 사용자가 복제본을 변경하고자 할 때 프로그램은 이러한 상기시키는 기능을 없앨 것이다. 사용자가 이후에 복제본을 다시 변경할 때 프로그램은 원본을 접근할 수 있게 해야 하며 사용자가 원하면 변경해야 하지만, 사용자가 원본을 변경해야 한다는 표시를 할 필요는 없다. 반면에 만일 사용자가 원본을 변경하면, 프로그램은 어떠한 복제본들을 역시 변경해야 하는지를 알려주어야 한다. 마찬가지로 프로그램은 사용자에게 해당 내용을 보여주고 저장된 관계를 없앨 수 있도록 기능을 제공해야 한다.
마지막으로 한번 복사(copy-once) 기능은 다섯번째 사용 시나리오 – 텍스트를 복사하고 원본과 복제본 간의 논리적인 관계를 내부적으로 정의하기 원하지 않으면서 변경 가능성이 있는 경우 - 와 관련이 있다. 이는 일반적인 복사(copy)-붙여넣기(paste)와 유사하며, 사용자가 텍스트를 복사하지만 프로그램은 원본과 복제본 간의 어떠한 관계도 저장하지 않으며 사용자에게 불일치성 문제를 회피하게 하는데 도움을 주지 않는다. 이 기능은 또한 복사(copy) 및 붙여넣기(paste)에 길들여졌지만 새로운 기능에 익숙해지기를 원하지 않는 사람 뿐만 아니라 컴퓨터가 사용자보다 더 지적일 경우 성가시게 되는 사람들을 위한 것이다.
위의 네가지 기능과 더불어서, 프로그램은 다음 기능을 위한 텍스트를 표시하는 방법을 제공해야 한다. 클립보드에 무언가를 복사하는 것과는 반대로 표시 기능은 다음 기능에 대해서 아무런 부수 효과를 남기지 않는다. 이것은 클립보드에서 무언가를 삭제하는 방법이 없기 때문에 기존 복사(copy)-붙여넣기(paste)에서는 불가능하다.

예제

위의 기능들이 어떻게 동작하는지를 설명하기 위해서 평면의 점을 표현하는 자바 클래스를 만들기 원하는 프로그래머가 있다고 가정하자.

사용자 삽입 이미지

프로그래머는 다음 그림의 (a)과 같이 코드를 작성하기 시작할 것이다.

이 시점에서 그림 (b)와 같이 첫번째 복사를 위한 시간이 흘렀다. 프로그래머는 xCoordinate 라는 정의를 복사하여 yCoordinate로 복제본의 속성명을 변경한다. 프로그래머는 두개의 선간에 논리적인 연결이 있기 때문에 (두개의 좌표에 대한 정의가 비슷하다는 일은 발생되지 않는다) 복사 후 변경(copy-and-change) 기능을 사용하지만, 물론 두개의 선은 일치한다는 의미는 아니다.
이제 프로그래머는 그림 (c)와 같이 속성 중 하나에 대한 get 메소드를 추가 – 특별한 복사 기능을 사용해서 - 한다. 프로그래머가 return 구문에 대해서 동일 복사 (copy-identical) 기능을 사용하고 있음을 유의하라. 이는 return 되는 변수의 이름이 해당 변수의 선언의 이름과 일치해야 하기 때문이다. 반면에, public 은 한번 복사 (copy-once)를 사용해서 복사하고 있는데, 이는 클래스의 public 과 get 메소드의 public 사이에는 아무런 논리적인 연결이 존재하기 않기 때문이다. 타이핑의 양을 줄이기 위해서, 두개의 public이 일치한다는 것을 고작해야 이용할 뿐이다.

구현 문제

동일 복사 (copy-identical) 기능과 관련 자동 수정을 구현하는 것은 사소하지 않다. 사용자는 동일 복사(copy-identical) 기능을 동일 복사(copy-identical) 을 사용해서 이전에 복사했던 구역에 포함하거나 포함되는 텍스트에 적용할 수 있다. 따라서, 프로그램은 복사된 구역 간의 두 관계를 저장해야 한다. 일치(동일 관계)를 유지해야 하는 구역과 부분(is-part-of) 관계.
복사 후 변경 (copy-and-change) 기능을 구현하는 것은 마찬가지로 복사 후 변경(copy-and-change) 기능이 복사 후 변경(copy-and-change) 을 사용해서 복사된 또 다른 구역을 포함하거나 부분이 될 수도 있기 때문에 유사하다. 따라서, 구역 구조는 이 경우 역시 중요하다. 유일한 차이는 다른 편에 저장된 관계 – 한편으로부터 복사된 구역 - 가 대칭이 아니라는 것이다. 동일 복사(copy-identical) 기능에서 기능의 방향성은 중요하지 않은데, 이는 목적이 일치된 구역을 유지하는 것이기 때문이다. 하지만, 복사 후 변경(copy-and-change) 기능에서 원본과 복제본의 역할이 약간 다르다.
물론, 동일 복사(copy-identical)와 복사 후 변경(copy-and-change) 기능이 정의하는 관계는 독립적이 아니다. 예를 들어, 동일 복사(copy-identical)을 사용해서 복사된 텍스트는 복사 후 변경(copy-and-change) 기능에 관련된 텍스트의 또 다른 구역을 포함할 수 있다. 따라서, 프로그램은 모든 세가지 관계 – 동일 복사(copy-identical)과 복사 후 변경(copy-and-change) 및 부분(is-part-of) 관계에 의해 만들어진 관계 - 를 고려해야 한다.
프로그램은 또한 이러한 관계를 영구적으로 저장함으로써 단일 편집 세션을 넘어서서 기능을 더 강화할 수 있다. 일반적으로 이것은 문서를 포함하는 파일에 이러한 관계들을 저장함을 의미한다. 또 다른 가능성 있는 전략은 이러한 정보와 같이 실제 파일이 혼재되는 것을 피하기 위해서 부수적인 파일에 관계를 저장하는 것이다. 예를 들어 소스 코드 에디터는 이러한 전략을 수용할 수 있는데, 소스 파일은 단지 프로그램 코드만을 포함해야 하기 때문이다.

사용자 삽입 이미지


이동(move)와 한번 복사(copy-once) 기능을 구현하는 것은 프로그램이 주어진 텍스트를 이동하거나 복사한 후 어떠한 추가 지원을 제공할 필요가 없기 때문에 유사한 문제를 일으키지는 않는다. 따라서 이러한 기능을 저장할 필요는 없다.
복사 기능으로 인해 발생되는 영구 저장되는 관계를 설명하기 위해서 위의 두번째 그림에서 첫번째 그림으로 유발된 관계를 보여주고 있다. 동일 복사 (copy-identical)이 나타내는 끝부분은 양쪽으로 화살표를 가지고 있으며, 이는 동일 복사(copy-identical)가 대칭 관계를 정의하기 때문이다. 반면에 복사 후 변경 (copy-and-change) 기능에서 나타나는 끝부분은 원본에서 복사본으로 향하고 있는데, 이는 복사 후 변경 (copy-and-change)가 비대칭 관계를 정의하기 때문이다. 한번 복사 (copy-once) 기능은 문서 일치성에 아무런 영향을 미치지 않기 때문에 위의 표현에 나타나지 않는다.

관계 적용하기

제안한 프로그램의 장점을 설명하기 위해서 이전의 예제에 기반한 시나리오를 고려해보자. 즉, 프로그래머는 이후에 private int xCoordinate 정의를 private int horizontalCoordinate로 변경한다고 하자. 에디터 프로그램은 두가지 가정을 만들 것이다. 첫번째는 yCoordinate라는 정의를 변경하는 것이다. 프로그래머는 yCoordinate 라는 정의를 만들기 위해서 복사 후 변경 (copy-and-change) 를 사용해서 변경된 정의를 복사했기 때문에 프로그램은 이러한 정의가 또한 변경할 필요가 있을 것이라고 제안한다. 그리고 실제로 프로그래머는 이를 verticalCoordinate로 변경하기를 원할 수도 있다.
두번째 제안은 horizontalCoordinate를 return 하는 getXCoordinate 메소드를 자동으로 변경하는 것이다. 프로그래머는 getXCoordinate 메소드의 return 구문에 동일 복사 (copy-identical)를 사용해서 xCoordinate 구역을 복사했기 때문에 프로그램은 horizontalCoordinate 를 반환하는 해당 라인을 자동으로 변경하게끔 제안할 것이며, 이는 프로그래머가 정확하게 원하는 것이다.

비록 위의 예제들은 대부분 프로그래밍 영역에서 왔지만, 제안한 기능은 그림이나 오디오, 혹은 비디오 파일이나 스프레드시트 셀의 부분과 같은 객체를 복사하는 데에도 역시 적합하다. 기능들은 복사된 객체들 간의 의미론적인 관계를 정의하는 데에 강력한 가능성을 제시하며 문서가 관계되는 일치성을 보장하는데 도움이 된다. 물론, 더 많은 유연성이 생김으로 인해서 최선의 선택을 더 세심하게 고려할 필요성은 있으며, 이는 다소 더 긴 학습 곡선을 의미하기도 하지만, 이러한 노력은 일치하지 않는 텍스트 복사에 대해서 걱정할 필요가 없다는 안도감에 대한 조그마한 대가이다. 이는 특히 오랜 시간 남아있는 문서에 대해서 더 그렇다.
한가지로 모든 것을 해결하는 것에 의지하는 대신 한가지 방법은 짧은 기간 남아 있는 텍스트에 대해서는 기존의 복사-붙여넣기(copy-paste)를 사용하고 오랜 시간 남아있는 텍스트에 대해서는 제안한 기능을 사용하는 것이다. 하지만 표시(mark), 이동(move), 한번 복사(copy-once)를 사용하는 것은 기존의 잘라내기(cut), 복사(copy), 붙여넣기(paste)와 거의 동일한 기능을 사용자에게 제공한다. 새로운 개념은 부가적인 동일 복사(copy-identical)과 복사 후 변경(copy-and-change) 기능 때문에 단순하게 그 범위가 더 넓다.
만일 사용자가 하나의 문서 내에서 객체들을 편집하고 복사하는 단 하나의 에디터 프로그램만을 사용한다면 이러한 모든 것이 잘 작동하고 구현하는데 비교적 쉽다. 모든 복사 작업은 에디터 프로그램의 영역에 위치하며, 따라서 이는 정의된 관계의 장시간 유지를 지원할 수 있다. 에디터 프로그램은 문서 영역을 가로지르는 복사에 대한 동일한 지원을 제공할 수도 있다. 이를 위해서 중앙 DB에 문서간 관계를 저장해야 할 것이다.
하지만, 사용자가 여러 에디터 프로그램을 의지해야 한다면 문제는 아주 빠르게 더 복잡해진다. 몇몇 사용자들은 선호하는 에디터를 각각 가지고 동일한 문서를 작성할 수도 있거나, 사용자들이 스프레드시트와 다이어그램 사이와 같은 서로 다른 문서 유형 사이의 객체를 복사하는 서로 다른 프로그램을 필요로 할 수도 있다. 프로그램 영역을 벗어나는 의미론적 관계를 관리하는 것은 OS가 제공해야 하고 에디터 프로그램이 표준화된 인터페이스를 통해서 접근해야 하는 일반화된 메커니즘을 명확하게 필요로 한다. 이러한 측면에서 상황은 클립보드의 상황과 유사해진다. 즉, OS는 프로그램 간의 복사 기능을 수행하기 위한 수단을 제공한다. OS 수준에서 제안한 기능을 위한 그러한 장치를 설계하는 것이 앞으로의 연구에 대한 중요한 목표이다.

[출처] IEEE Computer, July 2006

반응형