Why should I know this?

using의 올바른 사용법 본문

inverse-technic

using의 올바른 사용법

die4taoam 2019. 3. 13. 02:30
0. inverse-technic 소개
inverse-technic은 오픈소스를 다루는 과정에서 의미를 파악하기 어려웠던 구문들을 모아놓고 왜 해당 소스코드를 분석하기 어려웠는지를 고찰하고 해결방안을 공유해서 코딩의 기술을 공부하기 위해 만들어졌습니다.


1. 본문
"using" 키워드의 올바른 사용법

using은 C++에서 특정 type이나 function을 편하게 사용하기 위해 alias를 지어주는 키워드입니다.
다음은 v8에서 using을 사용하는 코드입니다.


using JSEntryFunction =
GeneratedCode<Object*(Object * new_target, Object * target,
Object * receiver, int argc, Object*** args)>;


GeneratedCode라는 class를 JSEntryFunction이라는 alias를 붙여 이후 코드부터는 JSEntryFunction을 사용합니다. GeneratedCode라는 class를 단순히 사용하기 보다 문맥적인 의미를 붙여주기 위해서 사용된 겁니다.



JSEntryFunction stub_entry =
JSEntryFunction::FromAddress(isolate, code->entry());


value = stub_entry.Call(orig_func, func, recv, argc, argv);


"JSEntryFunction stub_entry" & "GeneratedCode stub_entry"

두 문장이 전해주는 문맥적 의미는 매우 다르게 느껴집니다.


하지만 이게 과연 좋은 코드일까요? 저는 아니라고 생각합니다.


왜냐면 using키워드는 back-trace가 되지 않기 때문입니다.

만약 함수가 길어져 using 선언과 그를 활용하는 코드가 한 페이지에 표시되지 않거나 둘 간의 연관성을 찾을 수 없을 정도로 소스코드간의 연결성이 없을 경우 그를 인지하고 있지 않은 상태에서는 해당 type에 대한 back-trace를 하게 되고 재수가 없으면 유사한 type에서 삽질을 하거나 운이 좋더라도 한번더 작업을 해서 JSEntryFunction이라는 타입에 대한 정보를 찾아내야 해당 코드를 이해할 수 있습니다.


그러므로 다음처럼 변경하는게 바람직합니다.

마찬가지로 최근 버전 v8에서 사용되는 using 구문입니다.



if (params.execution_target == Execution::Target::kCallable) {
// clang-format off
// {new_target}, {target}, {receiver}, return value: tagged pointers
// {argv}: pointer to array of tagged pointers
using JSEntryFunction = GeneratedCode<Address(
Address root_register_value, Address new_target, Address target,
Address receiver, intptr_t argc, Address** argv)>;
// clang-format on
JSEntryFunction stub_entry =
JSEntryFunction::FromAddress(isolate, code->InstructionStart());
value = Object(stub_entry.Call(isolate->isolate_data()->isolate_root(),
orig_func, func, recv, params.argc, argv));
} else {
using JSEntryFunction = GeneratedCode<Address(
Address root_register_value, MicrotaskQueue* microtask_queue)>;
// clang-format on
JSEntryFunction stub_entry =
JSEntryFunction::FromAddress(isolate, code->InstructionStart());


using을 통해 문맥 정보를 높히면서도 그 정보를 이해하기 위한 수고를 하지 않게 만들기 위해 using과 그를 사용하는 코드 구문을 엮어서 해당 정보를 찾기 위해 스크롤링 할 일이 없도록 만들었습니다.



2. 마무리

저는 코딩하면서 라인수나 문자 수를 줄이기 위해 고민하는 것을 "좋은 코딩 습관"이라고 생각하는 경향이 있었습니다. 생각해보니 이는 해당 코드에 대한 지식을 도제식으로 전승할 수 있던 시절의 유산인것 같습니다. 하지만 현대에는 사회가 바뀌는 속도만큼 사람이 바뀌는 속도도 빠릅니다. 그러므로 더 이상 도제식, 사수 같은 암묵적 제도의 도움을 받을 수 없거나 줄 수 없는 경우가 많습니다. 


그래서 저의 결론은 코드를 코드만 봐도 이해할 수 있게 끔,

"코드의 문맥정보"를 높히는 코드가 더 좋은 코딩 습관입니다.




Comments