tools/vim

Learn Vimscript The Hard Way - 22: Comparision

seul chan 2020. 3. 28. 09:05

Comparisons

앞 장에서 배운 vimscript의 조건절은 비교가 없으면 그다지 유용하지 않을 것이다.

:if 10 > 1
:    echom "foo"
:endif
:if "foo" == "bar"
:    echom "one"
:elseif "foo" == "foo"
:    echom "two"
:endif

위에서 본 예시처럼 타 프로그램이 언어와 동일하게 비교를 사용 가능하다.

몇 가지 특이한 점들이 아래에서 설명될 예정

Case Sensitivity

다음을 실행시켜보자.

:set noignorecase
:if "foo" == "FOO"
:    echom "vim is case insensitive"
:elseif "foo" == "foo"
:    echom "vim is case sensitive"
:endif

당연히 elseif 아래가 실행되어 vim is case sensitive가 출력된다.

그럼 다음 예시를 실행시켜보자.

:set ignorecase
:if "foo" == "FOO"
:    echom "no, it couldn't be"
:elseif "foo" == "foo"
:    echom "this must be the one"
:endif

ignorecase 설정을 하자 if 아래가 실행된다 (!)

즉, ==는 유저의 세팅에 따라 작동한다.

Code Defensively

==는 유저의 세팅에 따라 작동한다.는 말은 다른 사람들이 사용하는 플러그인 등을 만들 때 절대로 == 비교를 믿을 수 없다는 말이다.

vim은 오래되고, 광범위하고, 복잡하기 때문에 플러그인을 작성할 때에 모든 유저가 모든 설정을 다양하게 사용한다고 가정해야 한다.

이 이상한 상황을 어떻게 처리할까? Vim은 두가지 등호를 더 가지고 있다.

:set noignorecase
:if "foo" ==? "FOO"
:    echom "first"
:elseif "foo" ==? "foo"
:    echom "second"
:endif

위 예시에서는 first가 반환된다.

==?는 유저의 세팅이 무엇이든지간에 case-insensitive를 등호에 적용한다.

:set ignorecase
:if "foo" ==# "FOO"
:    echom "one"
:elseif "foo" ==# "foo"
:    echom "two"
:endif

위 예시에서는 ignorecasecase-insensitive를 만들었음에도 fooFOO를 다르게 인식하여 two가 반환된다.

==#는 유저의 세팅이 무엇이든지간에 case-sensitive를 적용한다.

위 예시에서도 볼 수 있듯이, 어떤 상황에서든지 명시적인 sensitive, insensitive 등호를 사용하기를 강력하게 권장한다. 일반적인 등호 (==)는 어느 상황에서 반드시 문제를 맞닥뜨리게 된다.

숫자 비교에서는 ==#==?가 의미가 없지만, 둘 다 작동하기 때문에 습관을 위해 사용하는 것이 좋다고 한다.

Exercises

  • Play around with :set ignorecase and :set noignorecase and see how various comparisons act.

  • Read :help ignorecase to see why someone might set that option.

    은근히 smartcase가 헷갈릴 수 있겠다.

  • Read :help expr4 to see all the available comparison operators.

        use 'ignorecase'    match case       ignore case ~
equal            ==        ==#        ==?
not equal        !=        !=#        !=?
greater than        >        >#        >?
greater than or equal    >=        >=#        >=?
smaller than        <        <#        <?
smaller than or equal    <=        <=#        <=?
regexp matches        =~        =~#        =~?
regexp doesn't match    !~        !~#        !~?
same instance        is        is#        is?
different instance    isnot        isnot#        isnot?