Để hiểu rõ hơn làm thế nào bạn có thể đạt được những gì bạn muốn, hãy nhìn vào ví dụ sau:
module PrintingModule
def self.included(object)
object.extend(ClassMethods)
end
module ClassMethods
def class_method_of_class
puts "I am class #{self.name}"
end
end
def instance_method_of_class
puts "My name is: #{@name}"
end
class << self
def static_module_method
puts "Printer version 1.0"
end
end
end
class SomeObject
include PrintingModule
def initialize(name)
@name = name
end
end
object = SomeObject.new("Something")
object.instance_method_of_class
SomeObject.class_method_of_class
PrintingModule.static_module_method
Tôi hy vọng nó rõ ràng hơn bây giờ, lưu ý rằng đây chỉ là một trong những cách có thể (có những cách khác)
CẬP NHẬT: Tôi sẽ cố gắng cụ thể hơn. Khi bạn định nghĩa các phương thức instance/singleton trên module, những gì bạn đang thực sự làm là bạn định nghĩa các phương thức instance của lớp sẽ bao gồm module đó và mặt khác, các phương thức lớp được định nghĩa trên module sẽ trở thành các phương thức lớp của module đó. Điều thứ hai cần biết là attr_accessor tạo ra phương thức instance cho getter và setter của tham số đã cho.
Trả lời một phần câu hỏi của bạn, trong ví dụ đầu tiên bạn đang tạo 3 phương thức lớp trên lớp của mô-đun. Trong phương thức thứ hai, bạn đang tạo phương thức 1 lớp nơi bạn đang cố gắng truy cập một phương thức lớp khác (setter), nhưng getters và setters của bạn được định nghĩa là instance method = chúng sẽ trở thành instance của method class sẽ bao gồm module của bạn không thể nhận được cho họ theo cách này = bạn không có quyền truy cập vào getters và setters của bạn. Để giải thích về bản thân, tôi không giỏi lắm, nhưng theo như tôi biết, khi bạn sử dụng "class < < self" bạn đang mở eigenclass (mỗi đối tượng có riêng nó) của đối tượng (lưu ý rằng Lớp, mô-đun hoặc các thể hiện của các lớp cũng là các đối tượng của khóa học), nơi bạn đang định nghĩa các phương thức thể hiện. Class method của object trong Ruby = instance method của eigenclass của đối tượng. Vì vậy, bạn có thể làm điều này cho ví dụ:
text = "something"
class << text
def say_hi
puts "Hi!"
end
end
text.say_hi
Khi bạn tạo thể hiện của lớp (String trong ví dụ này), ví dụ mà được nó độc đáo của riêng lớp vô danh đó là lớp con của lớp đó. Trong ví dụ này, bạn đã định nghĩa phương thức cá thể trên eigenclass của lớp con ẩn danh của lớp String. Vì vậy, bạn có thể sử dụng phương thức "say_hi" trên đối tượng văn bản nhưng không sử dụng lớp String. Vì vậy, "class < < self" là mở những eigenclasses.
Mặt khác, "tự" một mình đại diện cho một đối tượng trong ngữ cảnh hiện tại, có nghĩa là giống nhau trong một số trường hợp (ví dụ: của bạn). Đối với phương thức self.included, nó chỉ là một phương thức gọi lại được gọi khi module được đưa vào lớp với tham số biểu diễn đối tượng (ở đây là SomeObject).
Tôi hy vọng rằng tôi đã trả lời ít nhất một phần câu hỏi của bạn. biết thêm thông tin ở đây: Difference between 'self.method_name' and 'class << self' in Ruby
Nếu bạn thực sự muốn tìm hiểu chi tiết của Ruby Lập trình meta, tôi khuyên các [Metaprogramming của Ruby cuốn sách của Paolo Perrotta] (http://pragprog.com/book/ppmetr/metaprogramming-ruby) . – sarnold