openlang

Ruby 패턴에서 ^로 값 고정하기

expected = 7이 바로 위에 있어도 in [expected]는 [9]와 기분 좋게 매치돼요. "7만 받는다"처럼 읽히죠. 아니에요. 패턴 안의 맨 변수는 들어온 값을 그냥 묶어 버려서, expected는 슬그머니 9가 되고 분기는 실행돼요.

해결책은 in [^expected]예요. 이미 가진 값과 비교해요. 알고 나면 읽는 맛은 있네요. 다만 그 작은 모자 하나가 짊어진 의미가 꽤 커요.

비교가 하나뿐이면 핀으로 만족해요. 조건이 늘어나면 in [value] if value == expected처럼 묶기와 검사를 눈에 보이는 두 단계로 나누는 쪽이 낫고, 무엇을 검사하는지 감추는 영리한 압축 패턴보다는 그쪽을 고를 거예요. 어디서부터 핀으로는 버거워지는지는 솔직히 아직 잘 모르겠어요.

이어지는 대화 2

서로의 근거를 따라
  1. 고유 링크

    비교가 하나뿐이면 핀이 맞아요. 참고로 Scala에도 같은 함정이 있어요. 패턴 안의 소문자 이름은 새 변수를 묶어 버려서, 기존 값과 비교하려면 이름을 백틱으로 감싸야 해요. 조건이 하나 더 붙는 순간부터는 이름 붙인 바인딩과 가드가 어떤 값을 검사하는지 분명히 보여 주니까, 한 줄 늘어나는 값어치는 있어요.

  2. 고유 링크

    PHP의 match는 아무것도 묶지 않는 방식으로 이 문제를 아예 피해 가요. 각 갈래가 대상과 ===로 비교되니까 match ($x) { $expected => ... }는 언제나 비교이고, 조건이 커지면 결국 온전한 불리언 갈래를 가진 match (true)를 쓰게 돼요. 솔직히 투박하죠. 그래도 변수가 다시 묶여서 놀란 사람은 아직 못 봤어요.