Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby는 오류를 숨기고 있습니다!

Ruby는 의도적으로 일부 오류 및 예외를 숨깁니다.

때때로 이것은 유용할 수 있습니다.

Kernel#loop를 사용할 때와 같이 블록이 있는 메소드, loop StopIteration일 때 중지됩니다. 예외가 발생합니다.

그러나 다른 경우에는 디버깅 세션이 훨씬 더 어려워질 수 있습니다.

몇 가지 예를 살펴보겠습니다!

숨겨진 예외:비교 가능한 모듈 + <=> 메서드

첫 번째 예는 Comparable 모듈 및 <=> 방법.

예시 :

class MyObject
  attr_accessor :value

  include Comparable

  def initialize(value)
    @value = value
  end

  def <=>(other)
    raise ArgumentError, "can't compare #{other.class} with #{self.class}" unless other.is_a?(MyObject)

    value <=> other.valuee
  end
end

mo1 = MyObject.new(10)
mo2 = MyObject.new(10)

p mo1 == mo2

이 예에 대해 이야기해 보겠습니다.

첫 번째 :

MyObject라는 클래스가 있습니다. , 하나의 attr_accessor valueComparable 포함 비교 방법을 추가하는 모듈(예:== , < , > ) 우리 반에.

이러한 비교 방법은 <=>를 기반으로 합니다. 방법.

Enumerable 메소드가 each을 기반으로 하는 것처럼 방법.

그럼 :

두 개의 개체(MyObject.new ) 동일한 값(10 ).

값이 같더라도 다른 개체입니다. , 이것은 중요합니다.

이제 이 두 개체를 비교하면 mo1 &mo2 우리는 false를 얻습니다. …

왜?

<=>에 오류가 있기 때문에 방법이지만 Ruby는 그 오류를 숨기고 있습니다!

자세히 보세요...

오류를 발견할 수 있습니까?

잘 찾으셨다면! 그렇지 않다면 괜찮습니다 🙂

여기 :

value <=> other.valuee

value 보기 ?

오타가 있는 것 같습니다!

일반적으로 NoMethodError가 발생합니다. 예외 및 우리는 문제가 무엇인지 꽤 빨리 알게 될 것입니다. 그러나 이 예에서는 그렇지 않습니다.

좋은 소식은 Ruby 2.3 이후로 이것이 변경되었다는 것입니다. 더 이상 숨겨져 있지 않으므로 오류를 볼 수 있습니다.

아직 이전 Ruby 버전을 실행 중인 경우 업그레이드해야 하는 또 다른 이유입니다.

숨겨진 예외:숫자 개체 + 강제 변환 방법

숨겨진 예외의 또 다른 예는 Numeric입니다. 개체(Float , Integer ) + coerce 방법.

예시 :

class MyObject
  attr_accessor :value

  def initialize(value)
    @value = value
  end

  def +(other)
    other = MyObject.new(other) if other.kind_of?(Numeric)

    value + other.value
  end

  def coerce(other)
    mo = MyObject.new
    mo.valuee = other

    [mo, self]
  end
end

mo1 = MyObject.new 10
mo2 = MyObject.new 10

p mo1 + mo2
# 20

p mo1 + 20
# 30

이것은 또 다른 MyObject입니다. 클래스이지만 새로운 메소드를 사용하여 + &coerce .

coerce 방법을 사용하면 호환되지 않는 두 유형으로 작업하고 함께 작동할 수 있도록 동일한 유형으로 변환할 수 있습니다.

이 경우 우리 클래스는 몇 초, 가격 또는 이와 유사한 어떤 숫자 값을 나타냅니다.

우리는 이러한 종류의 작업을 수행할 수 있기를 원합니다. :

mo1 + 20
20 + mo1

첫 번째 것(mo1 + 20 )는 +를 제어하기 때문에 쉽습니다. 방법.

하지만 Integer는 어떻습니까? 수업?

정수의 +를 변경할 수 있습니다. 구현하는 방법이지만 좋은 생각은 아닙니다. 🙂

해결책은?

coerce 구현 자신의 클래스에서 방법.

+ 한 가지 Integer의 메소드 개체가 이 메서드를 구현하는지 확인하고 구현하면 호출합니다.

이제 이 섹션의 시작 부분에 있는 코드 예제를 기억하십니까?

이렇게 하면 :

20 + mo1

30을(를) 보고 싶습니다. , mo1 값 때문에 10입니다. . 그러나 우리가 본 것은 다음과 같습니다.

MyObject can't be coerced into Fixnum

이전과 동일한 문제입니다!

coerce 내부에 오류가 숨겨져 있습니다. 방법.

mo.valuee = other

다시 한 번 오타가 있지만 오류가 말하는 내용이 아닙니다!

MyObject can't be coerced into Fixnum

좋은 소식이 있습니다. 이 동작은 Ruby 2.5에서 변경되므로 또 다른 숨겨진 오류가 사라질 것이므로 걱정할 필요가 없습니다.

요약

보시다시피 예외 숨기기를 피하려는 이유에 대한 좋은 예입니다. 내 책 Ruby Deep Dive에서 예외에 대해 자세히 알아볼 수 있습니다.

더 많은 사람들이 볼 수 있도록 이 게시물을 친구들과 공유해 주시면 감사하겠습니다.

읽어주셔서 감사합니다!