tôi đã dành một số thời gian chơi đùa với IRB và đến với điều này:
class BasicObject
def class
klass = class << self; self; end # get the object's singleton class
klass.superclass # the superclass of an object's singleton class is that object's class
end
end
Điều đó sẽ cung cấp cho bất kỳ đối tượng được thừa kế từ BasicObject một phương pháp #class
rằng bạn có thể gọi.
Sửa
Tiếp tục giải thích theo yêu cầu trong các ý kiến:
Giả sử bạn có đối tượng obj
đó là một thể hiện của lớp Foo
. obj
nhận các phương thức thể hiện của nó từ các phương thức được xác định trong lớp Foo
, ngoài các phương thức được xác định trong lớp cha của Foo
và như vậy trên chuỗi thừa kế. Ruby cho phép bạn xác định phương pháp trực tiếp trên một đối tượng mà chỉ có thể truy cập đến đối tượng đặc biệt như thế này
obj = Foo.new
def obj.hello
puts "hello"
end
obj.hello #=> hello
other_obj = Foo.new
other_obj.hello #=> Method missing error
Lý do bạn có thể làm điều này là bởi vì mỗi đối tượng có một cái gì đó gọi là một lớp singleton (hoặc đôi khi gọi một eigenclass) mà bạn đang thực sự xác định phương thức trên. Lớp đơn này thực sự tồn tại trong chuỗi kế thừa của đối tượng trực tiếp bên dưới lớp thực tế của đối tượng. Điều đó làm cho lớp thực tế của đối tượng, Foo
trong ví dụ này, lớp cha của lớp đơn của đối tượng.
Dòng class << self
bạn thấy trong câu trả lời là một cú pháp đặc biệt để nhập phạm vi lớp đơn của đối tượng. Vì vậy, trong ví dụ trên, bạn cũng có thể định nghĩa một phương thức trong lớp singleton của một đối tượng như thế này
class << obj
def goodbye
puts "goodbye"
end
end
obj.goodbye #=> goodbye
Vì vậy, các dòng class << self; self; end
đang mở lớp singleton của đối tượng (bất kể đối tượng hiện đang self
) và sau đó trở self
(self
có bây giờ trở thành lớp singleton), sau đó có thể được gán cho một biến để làm những gì bạn muốn.
Tôi khuyên bạn nên đọc Metaprogramming Ruby nếu bạn muốn giải thích rõ hơn về tất cả điều này. Nó chắc chắn cung cấp cho bạn một sự hiểu biết tốt hơn về mô hình đối tượng Ruby nói chung.
Nguồn
2012-04-03 02:30:44
Bạn có thể cho một ví dụ cụ thể hơn một chút về những gì bạn đang cố gắng làm? Bạn đang hỏi "Nếu tôi có một lớp Foo kế thừa từ BasicObject, có cách nào để xác định rằng một thể hiện của lớp đó là 'Foo' trái ngược với BasicObject" không? Không chắc chắn những gì bạn đang yêu cầu. –
Thực ra, có chính xác! Thay đổi bài đăng để làm rõ – Jwosty
'MyObjectSystem.class.name'? –