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

Phương pháp Hook được kế thừa trong Ruby - và các bài học về nuôi dạy con cái khác

Xin chào các em và các bậc phụ huynh, ahem Rubyists. Trong một bài báo trước, chúng ta đã đi sâu vào chuỗi tổ tiên. Trong bài đăng hôm nay, chúng ta sẽ đi sâu hơn vào việc nuôi dạy con cái và thừa kế. Chúng ta sẽ khám phá phương thức hook kế thừa và xem xét việc ngăn chặn kế thừa.

Khi trẻ em thừa kế 101:Phương pháp móc nối được kế thừa

Hãy bắt đầu với việc xem xét cách khai báo quyền làm cha mẹ. Ruby cung cấp một cách tương tác gọn gàng với một lớp khi nó được khai báo là lớp cha của một lớp khác.

class Parent
  def self.inherited(subclass)
    puts "#{subclass} inherits from Parent"
  end
end
 
class Child < Parent
end

Chạy mã này sẽ in ra "Con kế thừa từ Cha", là Parent.inherited phương thức được gọi khi Child lớp kế thừa từ Parent . Lưu ý rằng phương thức này lấy lớp con làm tham số— Child , trong trường hợp của chúng ta. Cơ chế này cho phép bạn tương tác với lớp Parent để xác định một tập hợp các hành vi chỉ khi nó được kế thừa. Theo hành vi, trong ngữ cảnh này, chúng tôi có nghĩa là sửa đổi, xác định hoặc xóa các biến, phương thức và hằng số trên lớp kế thừa hoặc lớp kế thừa.

Bây giờ, hãy xác định parent_name phương pháp trực tuyến:

class Parent
  def self.inherited(subclass)
    subclass.define_method :parent_name do
      "Daddy"
    end
  end
end
 
class Child < Parent
end
 
Child.new.parent_name # => "Daddy"

Ở đây, chúng tôi xác định một phương thức trên Child khi nó kế thừa từ Parent lớp, nhưng không thêm phương thức đó trực tiếp vào Parent lớp. Thay vào đó, nó chỉ được xác định khi một lớp khác kế thừa từ Parent .

Được rồi, chúng ta đã đề cập đến lý thuyết, bây giờ chúng ta hãy xem một ví dụ thực tế hơn trong cuộc sống của một Rubyist.

Ngăn chặn sự kế thừa của lớp

Trong Ruby on Rails, việc di chuyển cơ sở dữ liệu được xử lý bởi ActiveRecord::Migration lớp. Hãy cố gắng kế thừa trực tiếp từ lớp này.

class AddFirstnameToUsers < ActiveRecord::Migration
end
 
# => StandardError (Directly inheriting from ActiveRecord::Migration is not supported..)

Lỗi này xuất hiện do Ruby on Rails cung cấp một cơ chế ngăn chúng ta kế thừa từ lớp này. Vậy tại sao Ruby on Rails thực hiện cơ chế này?

Quá trình di chuyển được kết hợp chặt chẽ với một phiên bản cụ thể của Ruby on Rails. Thật vậy, API được cung cấp bởi lớp này có thể thay đổi một chút giữa 2 phiên bản. Vì vậy, để tránh phá vỡ quá trình di chuyển khi bạn nâng cấp Ruby on Rails, khuôn khổ buộc bạn phải chọn một phiên bản cụ thể của lớp ActiveRecord ::Migration. Điều này đảm bảo quá trình di chuyển của bạn diễn ra suôn sẻ.

class AddFirstnameToUsers < ActiveRecord::Migration[4.2]
end

Trong ví dụ trên, quá trình di chuyển của chúng tôi được kết hợp với ActiveRecord::Migration API được cung cấp với phiên bản 4.2 của Ruby on Rails. Vì vậy, ngay cả khi chúng tôi nâng cấp ứng dụng của mình lên phiên bản 5.0, quá trình di chuyển của chúng tôi sẽ vẫn chạy trơn tru vì chúng sẽ vẫn chạy với phiên bản 4.2 của ActiveRecord::Migration API.

Cách ngăn chặn hoạt động của việc thừa kế

Bây giờ chúng ta đã hiểu tại sao kế thừa bị ngăn chặn ở đây, hãy xem cách ActiveRecord::Migration này ngăn cản sự kế thừa. Tất cả logic được xác định trong ActiveRecord::Migration.inherited phương pháp.

class AddFirstnameToUsers < ActiveRecord::Migration[4.2]
end

Khi AddFirstnameToUsers của chúng tôi lớp kế thừa từ ActiveRecord::Migration , ActiveRecord::Migration.inherited phương thức hook được gọi.

module ActiveRecord
  class Migration
    def self.inherited(subclass) #:nodoc:
      super
      if subclass.superclass == Migration
        raise StandardError, "Directly inheriting from ActiveRecord::Migration is not supported. " \
          "Please specify the Rails release the migration was written for:\n" \
          "\n" \
          "  class #{subclass} < ActiveRecord::Migration[4.2]"
      end
    end
  end
end

Như chúng ta thấy, phương thức hook này kiểm tra xem lớp con (AddFirstnameToUsers ) kế thừa trực tiếp từ ActiveRecord::Migration . Nếu nó xảy ra, một lỗi sẽ được nâng lên. Đây là điểm đầu vào hoàn hảo để kiểm soát tính kế thừa.

Kết luận

Hôm nay, chúng ta đã đề cập đến những điều cơ bản về thừa kế và ngăn chặn thừa kế. Chúng tôi đã đề cập đến phương thức hook kế thừa và xem nó có thể rất tiện dụng như thế nào khi tương tác với lớp kế thừa / kế thừa một cách nhanh chóng.

Trong bối cảnh thế giới thực, hãy chú ý khi chơi với tính năng thừa kế. Hãy rất thận trọng khi bạn xóa hoặc ghi đè một phương thức hoặc lớp hiện có. Điều này có thể dẫn đến một số tác dụng phụ không mong muốn. Trẻ em có thể ngừng gọi bạn là bố.

Et Voilà, điều này kết thúc bài đăng của chúng tôi cho ngày hôm nay!