làm thế nào để làm việc này
dễ dàng: nó không. Không phải trong Ruby, dù sao đi nữa.
Giống như trong hầu hết các ngôn ngữ khác, có một số thực thể cốt lõi được cho là tồn tại đơn giản. Chúng rơi xuống từ bầu trời, hiện ra từ không khí mỏng, xuất hiện kỳ diệu.
Trong Ruby, một số trong những điều kỳ diệu là:
Object
không có một lớp cha, nhưng bạn không thể định nghĩa một lớp không có lớp cha, lớp cha trực tiếp ngầm luôn là Object
. [Lưu ý: có thể có các lớp siêu thực hiện được xác định là Object
, nhưng cuối cùng, sẽ có một lớp không có siêu lớp.]
Object
là một thể hiện của Class
, mà là một lớp con của Object
(có nghĩa là gián tiếp Object
là một thể hiện của Object
chính nó)
Class
là một lớp con của Module
, đó là một thể hiện của Class
Class
là một ví dụ của Class
Không có điều nào trong số này có thể được giải thích trong Ruby.
BasicObject
, Object
, Module
và Class
tất cả cần phải đồng thời tồn tại cùng lúc vì chúng có phụ thuộc vòng tròn.
Chỉ vì mối quan hệ này không thể được thể hiện trong mã Ruby, không có nghĩa là đặc tả ngôn ngữ Ruby không thể nói nó phải như vậy. Nó tùy thuộc vào người triển khai để tìm ra cách để làm điều này. Sau khi tất cả, việc thực hiện Ruby có một mức độ truy cập vào các đối tượng mà bạn là một lập trình viên không có.
Ví dụ, việc thực hiện Ruby đầu tiên có thể tạo ra BasicObject
, thiết lập cả superclass
con trỏ của nó và class
con trỏ của nó để null
.
Sau đó, nó tạo ra Object
, thiết lập con trỏ superclass
của nó để BasicObject
và class
con trỏ của nó để null
.
Tiếp theo, nó tạo ra Module
, thiết lập con trỏ superclass
của nó để Object
và class
con trỏ của nó để null
.
Cuối cùng, nó tạo ra Class
, thiết lập con trỏ superclass
của nó để Module
và class
con trỏ của nó để null
.
Bây giờ, chúng ta có thể ghi đè lên BasicObject
's, Object
' s, Module
's, và Class
' s class
con trỏ để trỏ đến Class
, và chúng tôi đang thực hiện.
Điều này rất dễ làm từ bên ngoài hệ thống, nó trông có vẻ lạ từ bên trong.
Khi chúng làm tồn tại, tuy nhiên, hoàn toàn có thể thực hiện hầu hết hành vi của chúng trong Ruby thuần túy. Bạn chỉ cần phiên bản barebones của các lớp đó, nhờ vào các lớp mở của Ruby, bạn có thể thêm bất kỳ chức năng bị thiếu nào sau này.
Trong ví dụ của bạn, class Class
không tạo ra một lớp mới có tên Class
, nó được mở lại lớp hiệnClass
, được ban cho chúng ta bởi môi trường runtime.
Vì vậy, nó là hoàn toàn có thể giải thích hành vi mặc định của Class#new
ở đồng bằng Ruby:
class Class
def new(*args, &block)
obj = allocate # another magic thing that cannot be explained in Ruby
obj.initialize(*args, &block)
return obj
end
end
[Lưu ý:. Trên thực tế, initialize
là tư nhân, vì vậy bạn cần phải sử dụng obj.send(:initialize, *args, &block)
để phá vỡ những hạn chế truy cập]
BTW: Class#allocate
là một trong những điều kỳ diệu đó. Nó phân bổ một đối tượng rỗng mới trong không gian đối tượng của Ruby, đó là một thứ không thể thực hiện được trong Ruby. Vì vậy, Class#allocate
là một cái gì đó phải được cung cấp bởi hệ thống thời gian chạy là tốt.
'Class.class # => Class' – Flexoid
Rùa là tất cả các con đường xuống! –
Xem thêm [Sự lộn xộn nghịch lý lớp/đối tượng] (http://stackoverflow.com/questions/7675774/the-class-object-paradox-confusion). –