2013-05-13 42 views
5

Câu hỏi mới:Tôi có thể thêm các phương thức lớp và các phương thức mẫu từ cùng một mô-đun không?

Tôi biết cách bao gồm và mở rộng công việc, những gì tôi tự hỏi là có cách nào để có cả phương thức lớp và phương thức từ một mô-đun không?

Đây là cách tôi làm điều đó với hai mô-đun:

module InstanceMethods 
    def mod1 
     "mod1" 
    end 
end 

module ClassMethods 
    def mod2 
     "mod2" 
    end 
end 

class Testing 
    include InstanceMethods 
    extend ClassMethods 
end 

t = Testing.new 
puts t.mod1 
puts Testing::mod2 

Cảm ơn đã dành thời gian của bạn ...

Trả lời

9

Có một thành ngữ phổ biến cho điều đó. Nó sử dụng móc mô hình đối tượng included. Móc này được gọi mỗi khi một mô-đun được bao gồm vào một mô-đun/lớp

module MyExtensions 
    def self.included(base) 
    # base is our target class. Invoke `extend` on it and pass nested module with class methods. 
    base.extend ClassMethods 
    end 

    def mod1 
    "mod1" 
    end 

    module ClassMethods 
    def mod2 
     "mod2" 
    end 
    end 
end 

class Testing 
    include MyExtensions 
end 

t = Testing.new 
puts t.mod1 
puts Testing::mod2 
# >> mod1 
# >> mod2 

Cá nhân tôi cũng thích nhóm phương pháp mẫu cho mô-đun lồng nhau. Nhưng đây là thực tế ít được chấp nhận, theo như tôi biết.

module MyExtensions 
    def self.included(base) 
    base.extend ClassMethods 
    base.include(InstanceMethods) 

    # or this, if you have an old ruby and the line above doesn't work 
    # base.send :include, InstanceMethods 
    end 

    module InstanceMethods 
    def mod1 
     "mod1" 
    end 
    end 

    module ClassMethods 
    def mod2 
     "mod2" 
    end 
    end 
end 
+0

Cảm ơn bạn đã thanh toán bù trừ này ra cho tôi. Xóa thông tin mô tả. Cảm ơn bạn rất nhiều vì đã dành thời gian. –

+0

Xem câu trả lời của tôi cho một đơn giản hóa khá gọn gàng về điều này. :) – Magne

2
module Foo 
def self.included(m) 
    def m.show1 
    p "hi" 
    end 
end 

def show2 
    p "hello" 

end 
end 

class Bar 
include Foo 
end 

Bar.new.show2 #=> "hello" 
Bar.show1 #=> "hi" 
+0

Cảm ơn bạn đã dành thời gian, Sergio nhận câu trả lời được chấp nhận như lần đầu tiên. –

0

Yes. Đó là chính xác đơn giản như bạn mong đợi, do sự thiên tài của ruby:

module Methods 
    def mod 
     "mod" 
    end 
end 

class Testing 
    include Methods # will add mod as an instance method 
    extend Methods # will add mod as a class method 
end 

t = Testing.new 
puts t.mod 
puts Testing::mod 

Hoặc, bạn có thể làm:

module Methods 
    def mod1 
     "mod1" 
    end 

    def mod2 
     "mod2" 
    end 
end 

class Testing 
    include Methods # will add both mod1 and mod2 as instance methods 
    extend Methods # will add both mod1 and mod2 as class methods 
end 

t = Testing.new 
puts t.mod1 
puts Testing::mod2 
# But then you'd also get 
puts t.mod2 
puts Testing::mod1 
+0

Và nếu bạn cần một móc như 'self.included', thì bạn cũng có thể sử dụng' self.extended'. Xem https://www.sitepoint.com/hitchhikers-guide-to-metaprogramming-classmodule-hooks/ – Magne

+0

Tôi không nghĩ rằng bạn đã hiểu câu hỏi. :) Hãy tưởng tượng một mô-đun/mối quan tâm mang hai bộ phương pháp dự định: một để trở thành các phương thức thể hiện, và các phương thức [instance] lớp khác. Câu hỏi đặt ra là: làm thế nào để thêm cả hai (khác biệt!) Bộ phương pháp từ cùng một mô-đun. –

+0

Tôi nhận ra đó là một cách để giải thích nó. Nhưng tbh, câu hỏi không rõ ràng về nhu cầu về hai phương thức riêng biệt (mặc dù mã ví dụ hiện tại của anh ta đòi hỏi nó). Vẻ đẹp của nó là một mô-đun có thể bất khả tri như thế nào nó được sử dụng. Bạn không cần phải đoán trước cách các phương thức trong mô-đun sẽ được sử dụng. Tuy nhiên, nếu bạn có nhiều phương thức trong mô-đun, và đã thực hiện cả một phép bao gồm và mở rộng thì bạn sẽ có tất cả các phương thức có sẵn như là cả hai phương thức instance và class (không phân biệt). – Magne

Các vấn đề liên quan