Ruby - Mô-đun và Mixin
Mô-đun là một cách nhóm các phương thức, lớp và hằng số lại với nhau. Mô-đun mang lại cho bạn hai lợi ích chính.
Mô-đun cung cấp một không gian tên và ngăn chặn xung đột tên.
Các mô-đun thực hiện cơ sở mixin .
Mô-đun xác định một không gian tên, một hộp cát trong đó các phương thức và hằng số của bạn có thể chơi mà không phải lo lắng về việc bị các phương thức và hằng số khác dẫm lên.
Cú pháp
module Identifier
statement1
statement2
...........
end
Hằng số mô-đun được đặt tên giống như hằng số lớp, với một ký tự viết hoa đầu tiên. Các định nghĩa phương thức cũng giống nhau: Các phương thức mô-đun được định nghĩa giống như các phương thức lớp.
Như với các phương thức lớp, bạn gọi một phương thức mô-đun bằng cách đặt trước tên của nó bằng tên mô-đun và một dấu chấm, và bạn tham chiếu đến một hằng số bằng cách sử dụng tên mô-đun và hai dấu hai chấm.
Thí dụ
#!/usr/bin/ruby
# Module defined in trig.rb file
module Trig
PI = 3.141592654
def Trig.sin(x)
# ..
end
def Trig.cos(x)
# ..
end
end
Chúng ta có thể xác định thêm một mô-đun có cùng tên chức năng nhưng chức năng khác nhau -
#!/usr/bin/ruby
# Module defined in moral.rb file
module Moral
VERY_BAD = 0
BAD = 1
def Moral.sin(badness)
# ...
end
end
Giống như các phương thức lớp, bất cứ khi nào bạn định nghĩa một phương thức trong một mô-đun, bạn chỉ định tên mô-đun, theo sau là dấu chấm và sau đó là tên phương thức.
Ruby yêu cầu Tuyên bố
Câu lệnh request tương tự như câu lệnh include của C và C ++ và câu lệnh import của Java. Nếu một chương trình thứ ba muốn sử dụng bất kỳ thành phần định nghĩa, nó chỉ đơn giản có thể tải các tập tin mô-đun sử dụng Ruby yêu cầu tuyên bố -
Cú pháp
require filename
Ở đây, không bắt buộc phải đưa .rb phần mở rộng cùng với tên tệp.
Thí dụ
$LOAD_PATH << '.'
require 'trig.rb'
require 'moral'
y = Trig.sin(Trig::PI/4)
wrongdoing = Moral.sin(Moral::VERY_BAD)
Ở đây chúng tôi đang sử dụng $LOAD_PATH << '.'để Ruby biết rằng các tệp bao gồm phải được tìm kiếm trong thư mục hiện tại. Nếu bạn không muốn sử dụng $ LOAD_PATH thì bạn có thể sử dụngrequire_relative để bao gồm các tệp từ một thư mục tương đối.
IMPORTANT- Ở đây, cả hai tệp đều chứa cùng một tên hàm. Vì vậy, điều này sẽ dẫn đến sự mơ hồ về mã khi bao gồm trong chương trình đang gọi nhưng các mô-đun tránh được sự mơ hồ về mã này và chúng ta có thể gọi hàm thích hợp bằng cách sử dụng tên mô-đun.
Câu lệnh bao gồm Ruby
Bạn có thể nhúng một mô-đun vào một lớp. Để nhúng một mô-đun vào một lớp, bạn sử dụng câu lệnh include trong lớp:
Cú pháp
include modulename
Nếu một module được định nghĩa trong một file riêng biệt, sau đó nó là cần thiết để bao gồm rằng tập tin sử dụng yêu cầu tuyên bố trước khi nhúng mô-đun trong một lớp học.
Thí dụ
Hãy xem xét mô-đun sau được viết trong tệp support.rb .
module Week
FIRST_DAY = "Sunday"
def Week.weeks_in_month
puts "You have four weeks in a month"
end
def Week.weeks_in_year
puts "You have 52 weeks in a year"
end
end
Bây giờ, bạn có thể bao gồm mô-đun này trong một lớp như sau:
#!/usr/bin/ruby
$LOAD_PATH << '.'
require "support"
class Decade
include Week
no_of_yrs = 10
def no_of_months
puts Week::FIRST_DAY
number = 10*12
puts number
end
end
d1 = Decade.new
puts Week::FIRST_DAY
Week.weeks_in_month
Week.weeks_in_year
d1.no_of_months
Điều này sẽ tạo ra kết quả sau:
Sunday
You have four weeks in a month
You have 52 weeks in a year
Sunday
120
Mixin trong Ruby
Trước khi xem qua phần này, chúng tôi cho rằng bạn đã có kiến thức về các khái niệm hướng đối tượng.
Khi một lớp có thể kế thừa các tính năng từ nhiều hơn một lớp cha, thì lớp đó phải hiển thị đa kế thừa.
Ruby không hỗ trợ đa kế thừa trực tiếp nhưng Ruby Modules có một công dụng tuyệt vời khác. Khi đột quỵ, họ loại bỏ khá nhiều nhu cầu về đa kế thừa, cung cấp một cơ sở gọi là mixin .
Mixin cung cấp cho bạn một cách được kiểm soát tuyệt vời để thêm chức năng vào các lớp. Tuy nhiên, sức mạnh thực sự của chúng xuất hiện khi mã trong mixin bắt đầu tương tác với mã trong lớp sử dụng nó.
Hãy để chúng tôi kiểm tra mã mẫu sau để hiểu rõ về mixin:
module A
def a1
end
def a2
end
end
module B
def b1
end
def b2
end
end
class Sample
include A
include B
def s1
end
end
samp = Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1
Mô-đun A bao gồm các phương pháp a1 và a2. Mô-đun B bao gồm các phương pháp b1 và b2. Lớp Sample bao gồm cả hai mô-đun A và B. Lớp Sample có thể truy cập vào tất cả bốn phương thức, cụ thể là a1, a2, b1 và b2. Do đó, bạn có thể thấy rằng lớp Sample kế thừa từ cả hai mô-đun. Do đó, bạn có thể nói lớp Sample hiển thị đa kế thừa hoặc một mixin .