prosource

긴-if 조건을 위한 PSR-2 표준

probook 2023. 9. 15. 21:08
반응형

긴-if 조건을 위한 PSR-2 표준

저는 이 경우에 대한 기준을 찾지 못했습니다.

if ($a == $b && $b == $c && $c == $d && $g == $d) {

}

아니면

if (($a == $b && $b == $c) && ($c == $d && $g == $d)) {

}

var-name이 더 길고 80자를 초과한다고 상상해보세요.어떻게 처리해야 합니까?다음과 같이 보일 수 있습니다.

if (
       $a == $b
    && $b == $c
    && $c == $d
    && $g == $d
) {

    }

저는 개인적으로.

if ($a == $b
    && $b == $c
    && $c == $d
    && $g == $d
) {
    // code here...
}

각 선에 대해 이중 앰퍼샌드로 시작하여 다음 문장이 다른 문장과 별개임을 나타냅니다.앰퍼샌드를 줄 끝에 놓으면 줄의 길이가 많이 달라지면 덜 티가 날 수 있습니다.

예를 들어,

if ($a == $b && 
    $b == $c && 
    $thisisamuchlongerstatementbecauseofthisvar == $d && 
    $g == $d
) {
    // code here...
}

이 경우 코드를 더 스캔해야 각 라인이 이중 앰퍼샌드로 연결되는지 알 수 있습니다.

이 사건에 대한 권고/규약은 없으며, Halcyon이 이미 언급했듯이 이것은 매우 예외적인 사건입니다.

그러나 다음과 같은 파라미터 목록이 긴 함수 호출에 대한 권장 사항이 있습니다.

인수 목록은 여러 줄에 걸쳐 분할될 수 있으며, 각 후속 줄은 한 번 들여쓰기됩니다.이 경우 목록의 첫 번째 항목은 다음 줄에 있어야 하며 한 줄에 인수가 하나만 있어야 합니다.

<?php
$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);

그래서 만약 내가 당신의 것과 비슷한 if-statement를 만들어야 한다면, 나는 이렇게 할 것입니다.

if (
    $a == $b &&
    $b == $c &&
    $c == $d &&
    $g == $d
) {
    // do something
}

이 직접 하지만, 저는 , 은, 는, 을 하는 것을 합니다.&&조건후 연산자.

PSR-2를 대체하는 새로운 표준 PSR-12가 이 질문을 명확하게 한다는 것을 언급할 필요가 있습니다.

괄호 안의 표현식은 여러 줄에 걸쳐 분할할 수 있으며, 각 후속 줄은 최소 한 번 이상 들여쓰기됩니다.이 경우 첫 번째 조건은 다음 라인에 있어야 합니다.닫는 괄호와 여는 괄호는 한 공간을 사이에 두고 자신의 선에 함께 배치해야 합니다.조건 사이의 부울 연산자는 항상 선의 시작이나 끝에 있어야 하며 둘 다 섞여서는 안 됩니다.

<?php

if (
    $expr1
    && $expr2
) {
    // if body
} elseif (
    $expr3
    && $expr4
) {
    // elseif body
}

출처 : https://www.php-fig.org/psr/psr-12/ #51-if-limitif-limitif-limitif-limites

편집

일년 후에, 나는 당신의 코드를 더 짧은 if문을 갖도록 다시 쓰는 것을 강력히 추천합니다.변수 또는 함수 호출을 통해.

원래의

저는 이런 상황에 처해서 다음과 같은 형식으로 진행하기로 했습니다.

if (
    $a == $b &&
    $b == $c &&
    $c == $d &&
    $g == $d) {
}

그러나 이전 코드를 PSR2 표준에 따라 다음과 같이 변환한 phpcbf를 사용합니다.

if ($a == $b &&
    $b == $c &&
    $c == $d &&
    $g == $d) {
}

더 알고 싶었습니다. 어디에도 기록되지 않은 경우 표준에서 예상하는 동작임을 어떻게 알 수 있습니까?자, 답은 간단합니다. 이 경우는 표준, 다음 문장에 의해 고려됩니다.

괄호 뒤에는 공백이 없어야 합니다.

이것은 두 번째 스니펫이 php-fig에 의해 선언된 PSR-2 표준을 따르는 유일한 스니펫인 이유를 설명합니다.

저는 주로 가독성과 버전 제어에서의 더 나은 동작을 위해 줄의 맨 앞에 문장이 있는 경우 논리 연산자를 길게 두는 것을 선호합니다.

다른 답변에서도 언급된 바와 같이 문장이 긴 경우 일반적으로 코드 냄새가 납니다.하지만 때로는 해야 하거나 코드가 이미 존재하여 다시 작성할 수 없기 때문에 이미 나쁜 일이라면 더 큰 혼란을 일으키지 않도록 도와줍니다.

또한 이러한 사항은 다른 요소가 너무 길기 때문에 여러 줄(예를 들어 긴 변수 또는 클래스 이름)로 분할해야 하는 경우에도 적용됩니다.

if (
    $something->getValue() === 'some_value'
    || (
        $something instanceof SomeClass
        && $something->has($someNumber)
        && $someNumber > 42
    )
) {
    // do something
}

가독성:모든 논리 연산자가 수직으로 그룹화되어 있기 때문에 각 선에 어떤 연산자가 있는지 바로 알 수 있습니다.눈이 코드를 스캔하기 때문에 수직으로 곧게 움직일 수 있으며 실제 추가 논리 레벨이 있을 때만 수평으로 움직일 수 있습니다.

조작자가 선의 끝에 있는 경우 눈은 균일하지 않은 선 사이에서 무작위로 앞뒤로 이동해야 합니다.

버전 제어에서 더 나은 동작:if 문 하단에 추가 절이 추가되면 버전 제어에서 1행이 추가되고 0이 제거됩니다.

diff --git a/3.php b/3.php
index 367c57c..2a40c3a 100644
--- a/3.php
+++ b/3.php
@@ -6,6 +6,7 @@ 
    if (
         $something instanceof SomeClass
         && $something->has($someNumber)
         && $someNumber > 42
+        && $anotherCase
    ) {
     // do something

논리 연산자를 끝에 두면 2개의 행이 추가되고 1개가 제거됩니다.마지막 변경에 대한 커밋 메시지는 Git 주석을 달 때 두 줄 모두에 대해 표시되므로 연산자를 추가한 줄에 대한 커밋 메시지를 보려면 이전 버전으로 이동해야 합니다.

diff --git a/4.php b/4.php
index f654780..2b9e0c5 100644
--- a/4.php
+++ b/4.php
@@ -5,7 +5,8 @@ 
    if (
        $something instanceof SomeClass &&
        $something->has($someNumber) &&
-       $someNumber > 42
+       $someNumber > 42 &&
+       $anotherCase
     ) {
     // do something

요즘 추천할만한게 있는데...PSR-12에서.

괄호 안의 표현식은 여러 줄에 걸쳐 분할할 수 있으며, 각 후속 줄은 최소 한 번 이상 들여쓰기됩니다.이 경우 첫 번째 조건은 다음 라인에 있어야 합니다.닫는 괄호와 여는 괄호는 한 공간을 사이에 두고 자신의 선에 함께 배치해야 합니다.조건 사이의 부울 연산자는 항상 선의 시작이나 끝에 있어야 하며 둘 다 섞여서는 안 됩니다.

<?php

if (
    $expr1
    && $expr2
) {
    // if body
} elseif (
    $expr3
    && $expr4
) {
    // elseif body
}

제가 가장 좋아하는 접근법은 IF 문에서 다음과 같이 하위 표현을 제거하는 것입니다.

$c1 = $a == $b;
$c2 = $b == $c;
$c3 = $c == $d;
$c4 = $g == $d;
if ($c1 && $c2 && $c3 && $c4) {
}

이 방법을 사용하면 디버그하는 것도 쉬워집니다.

두 번째 경우는 논리 연산자의 연관성으로 인해 첫 번째 경우와 동일합니다.그러므로,$a && $b && $c와 같음($a && $b) && $c, 와 같은.$a && ($b && $c)

저는 당신이 다른 용어로 그 운영에 대해 생각해보는 것을 제안합니다.예를 들어,

if (count(array_unique([$a, $b, $c, $d, $g])) == 1)

전체 알고리즘을 집합에 대한 연산으로 표현하고 개별 변수 대신 배열을 사용하며 위와 같이 집합에 대한 논리 연산을 사용할 수 있음을 알게 될 것입니다.그것은 급격하게 다른 코드와 더 읽기 쉬운 코드로 이어질 수 있습니다.

리팩토링의 또 다른 예:

namespace My;

UnexpectedValueException::assertAllEqual($a, $b, $c, $d, $g);


class UnexpectedValueException extends \UnexpectedValueException {

    public static function assertAllEqual(/* $value, ... */) {
        $args = func_get_args();
        if (count(array_unique($args)) > 1) {
            throw new static(sprintf('[%s] are not all equal', join(', ', $args)));
        }
    }

}

저는 처음에도 이를 선호합니다.

if (   self::LOG_ALL
    || (    self::DEBUG__EXECUTION_TIME__IS_ENABLED
        && (self::DEBUG__EXECUTION_TIME__THRESHOLD_SECONDS < $trxDurinationSeconds)
       )
) {
    doSomething();
}

저는 이런 스타일을 선호합니다.

if (condition1
|| (condition2_1 
    && condition2_2
    && condition2_3)
&& (c3 && c4) {
    // do something
}

하지만 다시 한번 말하지만, 가능한 한 간단한 것을 유지하세요.

큰 조건을 여러 개의 if로 분리하는 것이 더 나은 생각일 수도 있습니다.

당신의 질문을 위해, 나는 배열을 취하고 모두 true를 반환하는 함수를 만들 것입니다.&&충족.그럼, 내 메인 코드에서 당신은

$arr = [$a => $b, $b => $c, $c => $d];
// or you can create array of arrays [[$a, $b], [$b, $c] ...]

if (allTrue($arr))
    // do something

언급URL : https://stackoverflow.com/questions/23758916/psr-2-standard-for-long-if-conditions

반응형