원 라이너 vs. 가독성 : 코드 축소를 언제 중단해야합니까? [닫은]


14

문맥

최근에는 더 나은 형식의 코드를 만드는 데 관심이있었습니다. 그리고 더 나은 의미는 "충분한 사람들이 승인 한 규칙을 따르는 것이 좋습니다."

요즘에는 대부분 Ruby로 코드를 작성하기 때문에 linter (Rubocop)를 사용하여 코드의 "품질"에 대한 정보를 제공하기 시작했습니다 (이 "품질"은 커뮤니티 주도 프로젝트 ruby-style-guide에 의해 정의 됨 ).

나는 어떤 경우에는, 코드 효율성이 실제로 경우에도 그다지 코드의 효율성에 대해, "를 형식화하는 품질"과 "품질"을 사용할 것이라는 점을주의 한다 코드를 작성하는 방법에 의해 영향을 미쳤다.

어쨌든, 모든 것을하면서 나는 몇 가지 일을 깨달았습니다 (적어도 기억했습니다).

  • 일부 언어 (주로 Python, Ruby 등)는 훌륭한 코드를 만들 수 있습니다
  • 코드에 대한 몇 가지 지침을 따르면 코드가 훨씬 짧아 지지만 여전히 명확 해집니다.
  • 그러나이 지침을 너무 엄격하게 따르면 코드가 명확하지 않고 읽기가 쉽지 않습니다.
  • 이 코드는 일부 지침을 거의 완벽하게 준수 할 수 있지만 여전히 품질이 좋지 않습니다.
  • 코드 가독성은 대부분 주관적입니다 ( "명백한 것이 동료 개발자에게는 완전히 모호 할 수 있음").

이것들은 단지 절대적인 규칙이 아니라 단지 관찰입니다. 또한이 시점에서 코드 가독성과 지침을 따르지 않는 것처럼 보일 수 있지만 여기서는 지침이 하나의 코드를 다시 작성하는 방법의 수를 좁히는 방법입니다.

이제 몇 가지 예를 더 명확하게 설명하겠습니다.

간단한 사용 사례를 보자 : " User"모델을 가진 애플리케이션이있다 . 사용자는 선택 firstname적이고 surname필수 email주소를 가지고 있습니다.

최소한 " 또는 그 존재하는 경우 사용자의 name이름 ( firstname + surname)을 반환 firstname하거나 그렇지 않은 경우 대체 값으로 반환하는 " " 메소드를 작성하고 싶습니다 .surnameemail

또한이 메소드가 " use_email"를 매개 변수 (부울)로 사용하여 사용자 이메일을 폴백 값으로 사용할 수 있기를 원합니다 . 이 " use_email"매개 변수는 기본적으로 전달되지 않은 경우 " "로 설정해야합니다 true.

루비로 작성하는 가장 간단한 방법은 다음과 같습니다.

def name(use_email = true)
 # If firstname and surname are both blank (empty string or undefined)
 # and we can use the email...
 if (firstname.blank? && surname.blank?) && use_email
  # ... then, return the email
  return email
 else
  # ... else, concatenate the firstname and surname...
  name = "#{firstname} #{surname}"
  # ... and return the result striped from leading and trailing spaces
  return name.strip
 end
end

이 코드는 가장 간단하고 이해하기 쉬운 방법입니다. 루비를 "말하지"않는 사람에게도.

이제 더 짧게 만들어 봅시다 :

def name(use_email = true)
 # 'if' condition is used as a guard clause instead of a conditional block
 return email if (firstname.blank? && surname.blank?) && use_email
 # Use of 'return' makes 'else' useless anyway
 name = "#{firstname} #{surname}"
 return name.strip
end

이것은 쉽지는 않지만 더 짧고 이해하기 쉽습니다 (guard 절은 조건부 블록보다 읽기에 더 자연 스럽습니다). Guard 절은 또한 내가 사용하는 지침을보다 잘 준수하므로 여기에서 승리하십시오. 또한 들여 쓰기 수준을 줄입니다.

이제 좀 더 짧게하기 위해 Ruby 매직을 사용하자 :

def name(use_email = true)
 return email if (firstname.blank? && surname.blank?) && use_email
 # Ruby can return the last called value, making 'return' useless
 # and we can apply strip directly to our string, no need to store it
 "#{firstname} #{surname}".strip
end

더 짧고 지침을 완벽하게 준수하지만 반환 진술이 없기 때문에 명확하지 않으므로이 연습에 익숙하지 않은 사람들에게는 다소 혼란 스럽습니다.

우리가 질문을 시작할 수있는 곳이 여기 있습니다. 정말 가치가 있습니까? "아니오"라고 말하면 읽을 수있게하고 ' return'를 추가하십시오 (이를 알면 지침을 따르지 않음). 아니면 "괜찮아, 루비 방식이야, 젠장 언어를 배워라!"라고 말해야합니까?

옵션 B를 취하면 더 짧게 만들 수 없습니다.

def name(use_email = true)
 (email if (firstname.blank? && surname.blank?) && use_email) || "#{firstname} #{surname}".strip
end

여기는 하나의 라이너입니다! 물론 더 짧습니다 ... 여기서 우리는 루비 가 정의 된 값 에 따라 값 또는 다른 값을 반환한다는 사실을 이용합니다 (이메일은 이전과 동일한 조건에서 정의되므로).

우리는 또한 그것을 쓸 수 있습니다 :

def name(use_email = true)
 (email if [firstname, surname].all?(&:blank?) && use_email) || "#{firstname} #{surname}".strip
end

짧지 않고 읽기가 어렵지 않습니다 (저는 추악한 한 줄짜리 라이너가 어떻게 보이는지 보았습니다), 좋은 루비, 내가 사용하는 지침을 준수합니다 ...하지만 여전히 첫 번째 작성 방법과 비교 읽고 이해하기가 훨씬 쉽지 않습니다. 이 줄이 너무 길다 (80 자 이상).

질문

코드의 일부 예는 "풀 사이즈"코드와 여러 축소 버전 (유명한 한 줄짜리 줄) 중에서 선택하는 것이 어려울 수 있음을 알 수 있습니다. 여전히 가독성 측면에서 "전체 크기"코드를 능가하는 것은 없습니다.

여기 진짜 질문이 있습니다. 어디에서 멈출까요? 언제 짧고 짧습니까? 코드가 "너무 짧고"읽기 어려운 시점을 아는 방법 (주관적임을 명심)? 그리고 더 많은 것 : 항상 코드를 작성하고 느낌이 좋을 때 하나의 라이너를 "풀 사이즈"코드 덩어리와 섞지 않는 방법은 무엇입니까?

TL; DR

여기서 가장 중요한 질문은 "길지만 명확하고 읽기 쉽고 이해하기 쉬운 코드 덩어리"와 "한 줄을 읽고 이해하기 어려운 강력하고 더 짧지 만 이해하기 어려운"중에서 선택하는 것입니다. 두 가지 유일한 옵션이 아닌 척도의 맨 아래 : "충분히 명확함"과 "정확하지 않은 것"사이의 경계를 정의하는 방법은 무엇입니까?

주요 질문은 고전적인 "한 줄짜리 대 가독성 : 어느 쪽이 더 낫습니까?" "둘 사이의 균형을 찾는 방법은?"

편집 1

코드 예제의 주석은 "무시"되어야하며, 발생하는 상황을 명확하게하기 위해 여기에 있지만 코드의 가독성을 평가할 때 고려해서는 안됩니다.


7
대답이 너무 짧습니다. 이전 반복보다 나은지 확실하지 않을 때까지 반복적으로 리팩토링을 유지 한 다음 마지막 리팩토링을 중지하고 되돌립니다.
Dom

8
키워드가 추가 된 변형 3 return 선호합니다 . 그 일곱 캐릭터는 내 눈에 약간의 선명도를 더합니다.
cmaster-monica reinstate

2
정말로 끔찍한 느낌이 든다면, 모든 것을 [firstname,surname,!use_email].all?(&:blank?) ? email : "#{firstname} #{surname}".strip... 로 쓸 수 있습니다 . 왜냐하면 false.blank?true를 반환하고 삼항 연산자는 몇 개의 문자를 저장 하기 때문입니다 ... ¯ \ _ (ツ) _ / ¯
DaveMongoose

1
return키워드를 추가해야하는 명확성은 무엇 입니까?! 어떤 정보도 제공 하지 않습니다 . 순수한 혼란입니다.
Konrad Rudolph

2
간결함이 명료 함을 얻는다는 관념은 수익을 감소시키는 법칙을 겪을뿐 아니라 극단으로 밀릴 때 반대되는 개념입니다. 짧은 기능을 더 짧게 만들기 위해 다시 쓰고 있다면 시간을 낭비하고 연습을 정당화하려고 시도하는 것도 마찬가지입니다.
sdenham

답변:


26

어떤 코드를 작성하든 읽을 수있는 것이 가장 좋습니다. 짧은 것이 가장 좋습니다. 그리고 읽을 수있는 코드는 일반적으로 코드를 잘 이해하고 코드 명을 식별하고 코드가 작성되는 언어의 일반적인 관용구를 고수 할 수있을 정도로 짧아야합니다.

이것이 언어에 구애받지 않는다면, 이것은 분명히 의견에 근거한 것이라고 생각하지만, 루비 언어의 범위 내에서 우리는 그것에 대답 할 수 있다고 생각합니다.

먼저, 루비를 작성하는 기능과 관용적 방법은 return메소드에서 일찍 리턴하지 않는 한 값을 리턴 할 때 키워드 를 생략 하는 것입니다.

또 다른 특징과 관용구는 후행 if설명을 사용 하여 코드의 가독성을 높이는 것입니다. Ruby의 추진 아이디어 중 하나는 자연 언어로 읽는 코드를 작성하는 것입니다. 이를 위해 _why 's Poignant Guide to Ruby, Chapter 3으로 이동하십시오 .

다음을 소리내어 읽어보십시오.

5.times { print "Odelay!" }

영어 문장에서 구두점 (예 : 마침표, 느낌표, 괄호)은 조용합니다. 문장 부호는 단어에 의미를 더하고, 저자가 문장의 의도에 대해 힌트를줍니다. 위의 내용을 다음과 같이 읽겠습니다 : "Odelay!"

이를 감안할 때 코드 예제 # 3은 Ruby에 가장 관용적입니다.

def name(use_email = true)
  return email if firstname.blank? && surname.blank? && use_email

  "#{firstname} #{surname}".strip
end

이제 코드를 읽을 때 다음과 같이 말합니다.

이름이 비어 있고 성이 비어 있으면 이메일을 반환하고 이메일을 사용하십시오.

(반환) 이름과 성이 제거되었습니다.

실제 루비 코드와 거의 비슷합니다.

실제 코드는 2 줄에 불과하므로 꽤 간결하며 언어 관용구를 준수합니다.


좋은 지적이야 질문이 루비 중심이 아니었다는 것은 사실이지만, 여기서는 언어에 무관심한 대답을 할 수 없다는 데 동의합니다.
Sudiukil

8
나는 자연 언어처럼 코드 소리를 크게 과장하고 때로는 문제가 될 수 있다는 아이디어를 발견했다. 그러나이 동기가 없어도이 답변과 동일한 결론에 도달합니다.
Konrad Rudolph

1
코드에 대해 고려할 사항이 하나 더 있습니다. 즉, use_email함수 호출이 아닌 변수이기 때문에 다른 조건보다 우선합니다. 그러나 다시 문자열 보간법으로 인해 차이가 사라졌습니다.
John Dvorak

자연 언어 구조에 따라 코드를 구성하면 언어 함정에 빠질 수 있습니다. 예를 들어, 다음 요구 사항을 읽을 때 do send an email if A, B, C but no D전제에 따라 코딩하기가 더 쉬울 경우 2 개의 if / else 블록 을 입력하는 것이 당연 합니다 if not D, send an email. 자연어를 읽을 때주의하여 코드로 변환하십시오 . "Neverending story" 의 새 버전을 작성할 수 있기 때문 입니다. 클래스, 메소드 및 변수 결국 큰 문제는 아닙니다.
Laiv

@Laiv : 자연어처럼 코드를 읽는다고해서 문자 그대로 요구 사항을 번역하는 것은 아닙니다. 큰 소리로 읽을 때 모든 코드 비트, 문자 문자, 언어 구문의 언어 구문을 읽지 않고도 논리를 이해할 수 있도록 코드를 작성하는 것을 의미합니다. 코딩 if !D이 더 좋으면 D의미있는 이름 을 가진 것만 큼 ​​좋습니다 . 그리고 !연산자가 다른 코드 중에서 길을 잃은 경우 식별자가 호출되는 NotD것이 좋습니다.
Greg Burghardt

15

나는 당신이 "최고의 판단을하는 것"보다 더 나은 답변을 얻을 것이라고 생각하지 않습니다. 한마디로 당신을 위해 노력해야한다 선명도 보다는 곤란 . 종종 가장 짧은 코드도 가장 명확하지만, 만약 당신이 단지 부족함을 달성하는 데 집중한다면 선명도가 떨어질 수 있습니다. 이것은 마지막 두 예제에서 분명히 그렇습니다. 이전 세 예제보다 이해하기 위해 더 많은 노력이 필요합니다.

코드의 대상은 중요한 고려 사항입니다. 가독성은 물론 독서하는 사람에 전적으로 달려 있습니다. 코드를 읽을 것으로 기대하는 사람들 (자신 외에)이 실제로 루비 언어의 관용구를 알고 있습니까? 글쎄요,이 질문은 인터넷상의 임의의 사람들이 대답 할 수있는 것이 아닙니다.


나는 관객의 의견에 동의하지만 그것은 나의 투쟁의 일부이다 : 나의 소프트웨어는 종종 오픈 소스이기 때문에, 관객은 "루비 신들"뿐만 아니라 초보자들도 구성 할 수있다. 나는 대부분의 사람들이 접근 할 수 있도록 간단하게 만들 수는 있지만 언어가 제공하는 이점을 낭비하는 것처럼 느껴집니다.
Sudiukil

1
정말로 끔찍한 코드를 인계, 확장 및 유지해야하는 사람이 명확성을 확보해야합니다. 오래된 격언을 기억하십시오-관리자가 당신이 사는 곳과 아이들이 학교에가는 곳을 알고있는 복수형 지옥의 천사 인 것처럼 코드를 작성하십시오.
uɐɪ

2
@ Suudiukil : 그것은 중요한 포인트입니다. 나는 초보자가 어쨌든 오픈 소스 코드에 기여할 것 같지 않으므로 그러한 경우에 관용적 인 코드를 위해 노력할 것을 제안합니다 (즉, 언어에 대한 좋은 지식을 가정). (그렇다면 언어를 배우려고 노력할 것입니다.)
JacquesB

7

여기서 문제의 일부는 "가독성"입니다. 나를 위해 첫 번째 코드 예제를 봅니다.

def name(use_email = true)
 # If firstname and surname are both blank (empty string or undefined)
 # and we can use the email...
 if (firstname.blank? && surname.blank?) && use_email
  # ... then, return the email
  return email
 else
  # ... else, concatenate the firstname and surname...
  name = "#{firstname} #{surname}"
  # ... and return the result striped from leading and trailing spaces
  return name.strip
 end
end

그리고 코드를 반복하는 "잡음"주석으로 가득 차 있기 때문에 읽기가 어렵다는 것을 알게되었습니다. 그들을 제거하십시오 :

def name(use_email = true)
 if (firstname.blank? && surname.blank?) && use_email
  return email
 else
  name = "#{firstname} #{surname}"
  return name.strip
 end
end

이제 훨씬 더 읽기 쉬워졌습니다. 그런 다음 읽을 때 "음, 루비가 삼항 연산자를 지원하는지 궁금합니다. C #에서는 다음과 같이 작성할 수 있습니다.

string Name(bool useEmail = true) => 
    firstName.Blank() && surname.Blank() && useEmail 
    ? email 
    : $"{firstname} {surname}".Strip();

루비에서도 가능합니까? 귀하의 게시물을 살펴보면 다음과 같은 내용이 있습니다.

def name(use_email = true)
 (email if (firstname.blank? && surname.blank?) && use_email) || "#{firstname} #{surname}".strip
end

모든 좋은 물건. 그러나 그것은 읽을 수 없습니다. 전체 줄을 보려면 스크롤해야하기 때문입니다. 수정 해 봅시다 :

def name(use_email = true)
 (email if (firstname.blank? && surname.blank?) && use_email) 
 || "#{firstname} #{surname}".strip
end

이제 행복합니다. 구문이 어떻게 작동하는지 잘 모르겠지만 코드의 기능을 이해할 수 있습니다.

그러나 그것은 단지 나입니다. 다른 사람들은 코드를 읽기 좋게 만드는 것에 대해 다른 아이디어를 가지고 있습니다. 따라서 코드를 작성할 때 청중을 알아야합니다. 절대 초보자를 가르치는 경우 간단하게 유지하고 첫 번째 예와 같이 작성하는 것이 좋습니다. 오랜 세월의 루비 경험을 가진 전문 개발자들과 함께 일한다면 언어를 활용하는 코드를 작성하고 짧게 유지하십시오. 중간에 있다면 중간을 목표로하십시오.

그래도 한 가지 말하겠습니다. 마지막 예와 같이 "영리한 코드"에주의하십시오. 자신에게 물어보십시오. [firstname, surname].all?(&:blank?)이제 조금 읽기가 어려워도 기술을 과시하기 때문에 영리하게 느끼는 것 외에 다른 것을 추가합니까? 이 예제가 해당 범주에 완전히 포함되어 있다고 말할 수 있습니다. 그래도 5 개의 값을 비교한다면 좋은 코드로 볼 수 있습니다. 다시 말하지만, 여기에는 절대적인 선이 없으며 너무 영리하다는 것을 명심하십시오.

요약하면, 가독성을 위해서는 청중을 알고 코드를 적절하게 타겟팅하고 간결하지만 명확한 코드를 작성해야합니다. "영리한"코드를 작성하지 마십시오. 짧게 유지하지만 너무 짧지는 않습니다.


2
글쎄, 나는 그것을 언급하는 것을 잊었다. 그러나 그 의견은 "무시된다"는 의미로 루비를 잘 모르는 사람들을 돕기 위해 여기에있다. 청중에 대한 올바른 요점, 나는 그것에 대해 생각하지 않았습니다. 당신을 행복하게 만드는 버전에 관해서는 : 그것이 중요한 행 길이라면, 내 코드의 세 번째 버전 (하나의 return 문 만있는 것)은 그렇게하고 조금 더 이해하기 쉽습니다.
Sudiukil

1
@Sudiukil은 루비 개발자가 아니기 때문에 읽기가 가장 어려웠으며 "다른 언어의 관점에서"최고의 솔루션으로 찾고있는 것과 맞지 않습니다. 그러나 루비가 마지막 표현의 값을 반환하는 언어 중 하나라는 사실에 익숙한 사람에게는 가장 단순하고 읽기 쉬운 버전을 나타낼 가능성이 높습니다. 다시 말하지만, 그것은 모든 청중에 관한 것입니다.
David Arno

루비 개발자는 아니지만 "투표 할 내용은 다음과 같습니다. [각주 : 특정 긴 조건에서]] 늦게 도착한 문자열이 있습니다. 파티에." 본질적으로 단지 사례 진술인 논리는 하나의 통일 된 사례 진술처럼 작성되어야하며, 겉으로는 관련이없는 여러 진술에 퍼져서는 안됩니다.
Paul

개인적으로 나는 당신의 else 브랜치의 두 문장을 하나로 묶는 것을 제외하고는 두 번째 코드 블록으로 갈 것입니다.return "#{firstname} #{surname}".strip
Paul

2

이것은 아마도 의견 기반의 대답을하기가 어려운 질문 일지 모르지만 여기에는 2 센트가 있습니다.

코드를 더 짧게 만드는 것이 가독성에 영향을 미치지 않거나 심지어 향상시키는 경우가 있습니다. 코드를 읽을 수 없게되면 그렇게해야하는 이유가 상당히 있는지 고려해야합니다. 짧거나 시원하거나 할 수 있기 때문에하는 것이 나쁜 이유의 예입니다. 또한 코드를 짧게 만들면 다른 사람들이 이해하기 어려운 코드인지 고려해야합니다.

그렇다면 좋은 이유는 무엇입니까? 실제로는 판단 요청이지만 성능 최적화 (예 : 성능 테스트 후 사전은 아님)와 같은 예가 있습니다. 가독성이 떨어지면 기꺼이 지불 할 수있는 혜택이 있습니다. 이 경우 유용한 주석을 제공하여 단점을 완화 할 수 있습니다 (코드가 수행하는 작업 및 비트 암호로 만든 이유를 설명). 더 나은 방법으로, 해당 코드를 의미있는 이름을 가진 별도의 함수로 추출 할 수 있으므로 콜 사이트에서 세부 사항으로 이동하지 않고 (함수 이름을 통해) 발생하는 상황을 설명하는 단 한 줄에 불과합니다 (단, 사람이 다름) 이것에 대한 의견, 그래서 이것은 당신이해야 할 또 다른 판단 요청입니다.


1

대답은 약간 주관적이지만 한두 달 안에 코드를 다시 볼 때 이해할 수 있다면 정직하게 자신에게 물어봐야합니다.

각 변경 사항은 코드를 이해하는 평균적인 사람의 능력을 향상시켜야합니다. 코드를 이해하기 쉽게하려면 다음 지침을 따르는 것이 좋습니다.

  • 언어의 관용구를 존중 . C #, Java, Ruby, Python에는 모두 동일한 작업을 수행하는 선호하는 방법이 있습니다. 관용구는 익숙하지 않은 코드를 이해하는 데 도움이됩니다.
  • 코드를 읽을 수 없게되면 중지하십시오 . 제공 한 예에서 마지막 감소 코드 쌍을 쳤을 때 발생했습니다. 이전 예제의 관용적 이점을 잃어 버렸고 진행 상황을 진정으로 이해하기 위해 많은 생각이 필요한 많은 기호가 도입되었습니다.
  • 예상치 못한 것을 정당화해야 할 때만 주석을 사용하십시오 . Ruby에 익숙하지 않은 사람들에게 구문을 설명하기 위해 귀하의 예가 있다는 것을 알고 있습니다. 물론 괜찮습니다. 나는 주석을 사용하여 예기치 않은 비즈니스 규칙을 설명하고 코드 자체로 말할 수있는 경우 피하는 것을 선호합니다.

그러나 확장 된 코드가 더 나은 상황을 이해하는 데 도움이되는 경우가 있습니다. 그 예가 C #과 LINQ에서 나옵니다. LINQ는 훌륭한 도구이며 일부 상황에서는 가독성을 향상시킬 수 있지만 더 혼란 스러웠던 여러 가지 상황을 경험했습니다. 동료 검토에서 다른 if가 더 잘 유지할 수 있도록 적절한 if 문을 사용하여 표현식을 루프로 전환 할 것을 제안한 피드백이 있습니다. 내가 따랐을 때, 그들은 옳았다. 기술적으로 LINQ는 C #에 대해 관용적이지만 이해를 떨어 뜨리고 더 자세한 솔루션으로 개선하는 경우가 있습니다.

나는 이것을 말하기 위해 모든 것을 말한다.

코드를 더 잘 만들 수있게 개선 (더 이해하기 쉽게)

귀하 또는 귀하와 같은 사람은 나중에 해당 코드를 유지해야합니다. 다음에 오시면 몇 달이 지났을 것입니다. 코드를 이해할 수있는 비용으로 줄을 서서히 줄이십시오.


0

가독성 은 당신이 갖고 싶어하는 재산이지만 많은 일 라이너 가 아닙니다. 따라서 "한 줄짜리 대 가독성"보다는 문제는 다음과 같아야합니다.

원 라이너는 언제 가독성을 높이고 언제 손상을 줍니까?

나는 하나의 라이너가 다음 두 가지 조건을 충족시킬 때 가독성이 좋다고 생각합니다.

  1. 함수에 추출하기에는 너무 구체적입니다.
  2. 주변 코드를 읽는 "흐름"을 방해하고 싶지 않습니다.

예를 들어, name분석법의 이름이 좋지 않다고 가정 해 봅시다 . 이름과 성을 결합하거나 이름 대신 이메일을 사용하는 것은 자연스러운 일이 아닙니다. 따라서 name가장 좋은 방법 대신 길고 번거로운 결과를 얻을 수 있습니다.

puts "Name: #{user.email_if_there_is_no_name_otherwise_use_firstname_and_surname(use_email)}"

이러한 긴 이름은 이것이 매우 구체적이라는 것을 나타냅니다. 더 일반적인 경우 더 일반적인 이름을 찾을 수 있습니다. 따라서 메서드에 래핑해도 가독성 (너무 길다)이나 DRYness (너무 구체적으로 사용하기에는 너무 길지 않음)가 도움이되지 않으므로 코드를 그대로 두는 것이 좋습니다.

여전히-왜 하나의 라이너로 만드나요? 일반적으로 여러 줄 코드보다 읽기 어렵습니다. 이것은 두 번째 조건 인 주변 코드의 흐름을 확인 해야하는 곳입니다. 다음과 같은 것이 있다면 어떨까요?

puts "Group: #{user.group}"
puts "Title: #{user.title}"
if user.firstname.blank? && user.surname.blank?) && use_email
  name = email
else
  name = "#{firstname} #{surname}"
  name.strip
end
puts "Name: #{name}"
puts "Age: #{user.age}"
puts "Address: #{user.address}"

여러 줄로 된 코드 자체는 읽을 수 있지만 여러 줄로 구성된 주변 코드 (다양한 필드를 인쇄)를 읽으려고하면 해당 여러 줄 구문이 흐름을 방해합니다. 이것은 읽기 쉽다 :

puts "Group: #{user.group}"
puts "Title: #{user.title}"
puts "Name: #{(email if (user.firstname.blank? && user.surname.blank?) && use_email) || "#{user.firstname} #{user.surname}".strip}"
puts "Age: #{user.age}"
puts "Address: #{user.address}"

흐름이 중단되지 않으며 필요한 경우 특정 표현에 집중할 수 있습니다.

이게 당신의 사건입니까? 기필코 아니다!

첫 번째 조건은 관련성이 적습니다. 이미 메서드를 사용할 자격이있는 것으로 간주하고 구현보다 훨씬 읽기 쉬운 해당 메서드의 이름을 찾았습니다. 분명히 함수로 다시 추출하지 않을 것입니다.

두 번째 조건은 주변 코드의 흐름을 방해합니까? 아니! 주변 코드는 메소드 선언이며, 그것을 선택하는 name것이 유일한 목적입니다. 이름을 선택하는 논리는 주변 코드의 흐름을 방해하지 않으며 주변 코드의 목적입니다!

결론-전체 기능 바디를 하나의 라이너로 만들지 마십시오.

하나의 라이너는 흐름을 방해하지 않고 약간 복잡한 것을 원할 때 좋습니다. 함수 선언은 이미 흐름을 방해하므로 해당 함수를 호출 할 때 중단되지 않으므로 전체 함수 본문을 한 줄로 만드는 것이 가독성을 높이 지 않습니다.

노트

필자 일반적으로 주변 코드의 일부이며 흐름 내에 적합해야하는 인라인 함수 나 람다식이 아닌 "완전한"함수와 메서드를 참조 하고 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.