2013-02-08 14 views
5

Tôi có một mô-đun với các phương pháp ghi vào nhật ký. Vào mỗi tin nhắn tôi muốn đặt tên của lớp đã đăng nhập thông báo này.self.class.name trong mô-đun kết hợp

Mô-đun có thể được trộn lẫn trong việc sử dụng include hoặc extend. Tôi cần nhật ký của mình để có tên lớp chính xác trong từng trường hợp.

đang chưng cất:

module M 
    def f 
    self.class.name 
    end 
end 

class C 
    extend M 
    include M 
end 

p C.f # => "Class" 
p C.new.f # => "C" 

Như bạn thấy, cuộc gọi đầu tiên không đúng cách in "Class". Tôi cũng muốn nó là "C".

Làm cách nào để thực hiện việc này?

Trả lời

4

Không cần phải dùng đến lưỡi câu, chỉ cần thay đổi hành vi của bạn khi self là một Class/Module:

module M 
    def f 
    self.is_a?(Module) ? name : self.class.name 
    end 
end 

class C 
    extend M 
    include M 
end 

C.f  #=> "C" 
C.new.f #=> "C" 
3

Bạn có thể làm điều đó như thế này, không biết liệu có phương pháp tốt hơn hay không.

module M 
    def self.included(base) 
    base.extend ClassMethods 
    end 

    def f 
    self.class.name 
    end 

    module ClassMethods 
    def f 
     self.name 
    end 
    end 
end 

class C 
    include M 
end 
+0

này không làm việc ở tất cả nếu bạn 'mở rộng m', mặc dù. –

+0

Bạn không phải gia hạn. Các phương thức mà bạn muốn chuyển thành các phương thức lớp bạn đặt bên trong mô-đun ClassMethods. :) – Kaeros

+0

Nếu tôi chỉ muốn gia hạn và không bao gồm thì sao? Sau đó, tôi phải làm 'mở rộng M :: ClassMethods' không có lý do chính đáng. Cá nhân, tôi cũng thực sự không thích toàn bộ mô hình mở rộng khi đưa vào. –