class << self
không chỉ là một cách khai báo các phương thức của lớp (mặc dù nó có thể được sử dụng theo cách đó). Có thể bạn đã thấy một số cách sử dụng như:
class Foo
class << self
def a
print "I could also have been defined as def Foo.a."
end
end
end
Điều này hoạt động, và tương đương với def Foo.a
, nhưng cách nó hoạt động hơi tinh tế. Bí mật là self
, trong bối cảnh đó, tham chiếu đến đối tượng Foo
, có lớp là một lớp con ẩn danh, duy nhất của Class
. Lớp con này được gọi là Foo
's eigenclass . Vì vậy, def a
tạo ra một phương pháp mới gọi là a
trong Foo
's eigenclass, truy cập bằng cú pháp gọi phương thức bình thường: Foo.a
.
Bây giờ chúng ta hãy xem xét một ví dụ khác:
str = "abc"
other_str = "def"
class << str
def frob
return self + "d"
end
end
print str.frob
print other_str.frob
Ví dụ này giống với ví dụ cuối cùng, mặc dù ban đầu có thể khó nói. frob
được định nghĩa, không phải trên String
lớp, mà trên lớp eigenclass của str
, một lớp con ẩn danh duy nhất của String
. Vì vậy, str
có một frob
phương pháp, nhưng các trường hợp String
nói chung thì không. Chúng tôi cũng có thể có các phương thức được ghi đè của Chuỗi (rất hữu ích trong một số trường hợp thử nghiệm phức tạp).
Bây giờ chúng tôi được trang bị để hiểu ví dụ ban đầu của bạn. Foo
Phương thức khởi tạo của Inside , self
không đề cập đến lớp Foo
, mà là một số trường hợp cụ thể của Foo
. Eigenclass của nó là một lớp con của Foo
, nhưng nó không phải là Foo
; nó không thể được, hoặc nếu không thì thủ thuật chúng ta đã thấy trong ví dụ thứ hai không thể hoạt động. Vì vậy, để tiếp tục ví dụ của bạn:
f1 = Foo.new(:weasels)
f2 = Foo.new(:monkeys)
f1.weasels = 4
f2.monkeys = 5
print(f1.monkeys)
Hi vọng điêu nay co ich.