2012-11-06 15 views
8

Trong Ruby Tôi muốn có một lớp bao gồm một loạt các mô-đun và có các mô-đun riêng lẻ này thực hiện một khối hoặc phương thức (hoặc chỉ tìm cách chỉnh sửa biến mẫu) khi khởi tạo lớp học. Tôi biết tôi có thể làm điều này bằng cách tạo một phương thức trong module và sau đó gọi nó trong phương thức khởi tạo của lớp, nhưng tôi muốn một số cách để làm điều này bằng cách đơn giản bao gồm mô đun và gọi một phương thức để thực thi bất kỳ mã nào. , theo cách đó tôi có thể có một số lượng lớn các thứ được bao gồm trong một lớp mà không phải lo lắng về việc thêm một dòng mã trong phương thức khởi tạo cho mỗi mô-đun đơn được bao gồm. Tôi đã kiểm tra ra răng cưa, siêu, và những thứ liên quan nhưng đã không nhận bất cứ điều gì ... Nếu nó giúp để hiểu những gì tôi đang hy vọng sẽ hoàn thành đây là một số giả:Ruby: Thêm những thứ để khởi tạo phương thức thông qua các mô-đun

module Mod1 
    call_this_block_on_initialize { @a.push 4 } 
end 

module Mod2 
    call_this_block_on_initialize { @a.push 5 } 
end 

class Test 
    attr_accessor :a 
    include Mod1 
    include Mod2 

    def initialize 
     @a = [1, 2, 3] 
     call_those_blocks_set_by_mods 
    end 
end 

t = Test.new 
t.a # returns [1, 2, 3, 4, 5] 

Đây có thể là một chút dài dòng nhưng tôi nghĩ tiêu đề tổng kết những gì tôi đang cố gắng làm. Cảm ơn vì bất kì sự giúp đỡ!

Trả lời

7

Có một số cách bạn có thể thực hiện việc này. Ví dụ này sẽ xác định lại phương pháp khởi tạo và thêm bất cứ điều gì thêm mã bạn muốn:

module MyModule 
    def self.included(base) # built-in Ruby hook for modules 
    base.class_eval do  
     original_method = instance_method(:initialize) 
     define_method(:initialize) do |*args, &block| 
     original_method.bind(self).call(*args, &block) 
     @a.push 4 # (your module code here) 
     end 
    end 
    end 
end 

class Test 
    attr_accessor :a 

    def initialize 
    @a = [1, 2, 3]  
    end 

    # It must be included after the `initialize` 
    # definition or the module won't find the method: 
    include MyModule 
end 

Tuy nhiên: Tôi nghĩ rằng những gì bạn thực sự muốn là subclassing. Nếu bạn có nhiều lớp với hành vi tương tự, có vẻ như bạn làm, hãy tự hỏi nếu có một lớp cha mẹ trừu tượng tự nhiên. Bạn có thể giải thích những gì bạn đã làm với super và lý do tại sao nó không hoạt động?

+0

Bạn nói đúng, tôi đã xem xét cách siêu hoạt động và tôi có thể thực thi mã cho bất kỳ số lượng mô-đun nào được thêm vào bất kể kết hợp hoặc mô-đun nào. Về cơ bản đã thực hiện một chuỗi các siêu cho các mô-đun: – thIIIrd

+0

Đây là tiền rất, cảm ơn bạn. Tôi đã sử dụng điều này để tách ra các tệp 'ability.rb' cho mẫu ủy quyền Rails CanCan: http://stackoverflow.com/a/25723811/293280 –

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