Computer >> Máy Tính >  >> Lập trình >> Ruby

Ruby đang che giấu lỗi từ bạn!

Ruby sẽ cố tình ẩn một số lỗi và ngoại lệ khỏi bạn.

Đôi khi điều này có thể hữu ích.

Giống như khi sử dụng vòng lặp Kernel#loop phương thức với một khối, vòng lặp loop sẽ dừng khi StopIteration ngoại lệ được nêu ra.

Nhưng những lúc khác, điều này có thể khiến phiên gỡ lỗi của bạn khó hơn rất nhiều.

Hãy xem một số ví dụ!

Ngoại lệ ẩn:Mô-đun có thể so sánh + <=> Phương pháp

Ví dụ đầu tiên liên quan đến Comparable mô-đun &<=> phương pháp.

Đây là ví dụ :

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

Hãy nói về ví dụ này.

Đầu tiên :

Chúng tôi có một lớp tên là MyObject , với một giá trị attr_accessor loop và bao gồm Comparable mô-đun, bổ sung các phương pháp so sánh (như == , < , > ) đến lớp học của chúng tôi.

Các phương pháp so sánh này dựa trên <=> phương pháp.

Giống như các phương thức Enumerable dựa trên each phương pháp.

Sau đó :

Chúng tôi đang tạo hai đối tượng (MyObject.new ) với cùng một giá trị (10 ).

Lưu ý rằng ngay cả khi chúng có cùng giá trị chúng là các đối tượng khác nhau , điều này rất quan trọng.

Bây giờ nếu chúng ta so sánh hai đối tượng này mo1 &mo2 chúng tôi nhận được false

Tại sao?

Bởi vì chúng tôi có lỗi trong <=> của chúng tôi nhưng Ruby đang ẩn lỗi đó!

Nhìn kỹ…

Bạn có thể phát hiện ra lỗi không?

Nếu bạn tìm thấy nó là công việc tốt! Nếu không thì không sao 🙂

Đây rồi :

value <=> other.valuee

Xem valuee này ?

Hóa ra chúng tôi mắc lỗi đánh máy!

Thông thường, chúng tôi sẽ nhận được NoMethodError ngoại lệ và chúng tôi sẽ biết vấn đề là gì khá nhanh chóng. Nhưng không phải trong ví dụ này.

Tin tốt là kể từ Ruby 2.3, điều này đã thay đổi. Bạn có thể thấy lỗi ngay bây giờ vì nó không còn bị ẩn nữa.

Một lý do khác để nâng cấp nếu bạn vẫn đang chạy các phiên bản Ruby cũ hơn.

Ngoại lệ ẩn:Đối tượng số + Phương pháp cưỡng chế

Một ví dụ khác về ngoại lệ ẩn là với Numeric đối tượng (Float , Integer ) cộng với coerce phương pháp.

Đây là một ví dụ :

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

Đây là một MyObject khác lớp, nhưng với các phương thức mới, + &coerce .

coerce phương pháp này cho phép bạn làm việc với hai loại không tương thích và biến chúng thành cùng một loại để chúng có thể hoạt động cùng nhau.

Trong trường hợp này, lớp của chúng ta đại diện cho một số giá trị số, có thể là số giây, giá hoặc bất cứ thứ gì tương tự…

Và chúng tôi muốn có thể thực hiện những loại hoạt động này :

mo1 + 20
20 + mo1

Cái đầu tiên (mo1 + 20 ) dễ dàng vì chúng tôi kiểm soát + trong lớp của chúng tôi.

Nhưng còn Integer thì sao lớp học?

Chúng tôi có thể thay đổi + của Integer để thực hiện điều này, nhưng đó có lẽ không phải là một ý kiến ​​hay 🙂

Giải pháp?

Triển khai coerce trong lớp của riêng bạn.

Một điều là + phương thức trên Integer sẽ làm là kiểm tra xem đối tượng của bạn có triển khai phương thức này hay không và nếu có nó sẽ gọi nó.

Bây giờ, hãy nhớ ví dụ mã ở đầu phần này?

Nếu chúng tôi cố gắng làm điều này :

20 + mo1

Chúng tôi muốn xem 30 , vì giá trị cho mo110 . Nhưng những gì chúng ta thấy là:

MyObject can't be coerced into Fixnum

Vấn đề tương tự như trước đây!

Một lỗi đang được chúng tôi ẩn bên trong coerce phương pháp.

Cái này:mo.valuee = other

Một lần nữa, chúng tôi có một lỗi chính tả, nhưng đó không phải là lỗi đang nói!

MyObject can't be coerced into Fixnum

Tôi có tin tốt cho bạn, hành vi này đang thay đổi trong Ruby 2.5, do đó, đó sẽ là một lỗi ẩn khác sẽ biến mất, do đó bạn không phải lo lắng về nó.

Tóm tắt

Như bạn có thể thấy, đây là những ví dụ điển hình về lý do tại sao bạn muốn tránh ẩn các ngoại lệ. Bạn có thể tìm hiểu thêm về các trường hợp ngoại lệ trong cuốn sách của tôi, Ruby Deep Dive.

Tôi sẽ đánh giá cao nếu bạn chia sẻ bài đăng này với bạn bè của bạn để nhiều người có thể xem nó.

Cảm ơn vì đã đọc!