2012-02-25 26 views
5

Tôi đang phân tích mã nguồn của đường ray, vì tôi đã muốn hiểu các hoạt động bên trong của has_many và các cấu trúc tương tự.Làm thế nào là ruby ​​trên đường ray has_many (và tương tự) được thực hiện?

Cho đến nay, tôi đã có thể tìm thấy nơi phương pháp này được thực hiện (link to github): nó là trong module ActiveRecord :: Hội

def has_many(name, options = {}, &extension) 
    Builder::HasMany.build(self, name, options, &extension) 
end 

Cái này eventualy kết thúc (link to github) trong lớp ActiveRecord :: Các hiệp hội :: Builder :: CollectionAssociation as

def self.build(model, name, options, &extension) 
    new(model, name, options, &extension).build 
end 

Có những kỹ năng ruby ​​của tôi kết thúc và tôi không thể theo dõi nó thêm nữa và tìm nơi "mới" được triển khai và nó hoạt động như thế nào.

Ai đó có thể chỉ cho tôi đúng hướng và có thể nhận xét cùng, những gì đang diễn ra dưới mui xe?

+4

+1 cho perusing mã nguồn của các công cụ bạn đang sử dụng để đạt được một hiểu biết sâu hơn về ruột của họ. Con đường để đi. –

+1

@ s.m .: Tôi đồng ý. Nếu đọc mã nguồn không "hiển thị nỗ lực nghiên cứu" (như chú giải công cụ cho nút upvote nói), tôi không biết những gì! +1! –

+1

Cảm ơn mọi người đã trả lời. Tôi chấp nhận câu trả lời của Jörg, bởi vì nó là chi tiết nhất. Tôi cũng +1 Baldrik và s.m. là người đầu tiên trả lời. –

Trả lời

4

Về cơ bản, new được định nghĩa như thế này:

class Class 
    def new(*args, &block) 
    obj = allocate 

    obj.initialize(*args, &block) 
    # *actually* obj.send(:initialize, *args, &block) since initialize is private 

    obj 
    end 
end 

allocate được định nghĩa như thế này:

class Class 
    def allocate 
    # magic stuff for creating an empty object which cannot be expressed in Ruby: 

    new_obj = Deep::Within::VM.__somehow_magically_allocate_memory__! 

    new_obj.__class__ = self 

    new_obj 
    end 
end 
1

new gọi hàm tạo của lớp hiện tại. Hàm khởi tạo là phương thức initialize được xác định ngay sau phương thức self.build trong lớp CollectionAssociation. Đó là Ruby tinh khiết (ruby guide)

1

Để mở rộng câu trả lời của @ Baldrick, đúng là new được định nghĩa trong cả hai phương pháp lớp và phương pháp thể hiện và do đó có sẵn cho tất cả các lớp.

Điều gì new thực hiện việc gọi cả allocateinitialize (giả định phương pháp initialize đã được xác định).

+0

Tôi không nghĩ 'new' được định nghĩa là một phương thức lớp. Lớp 'Class' là một thể hiện của chính nó (yay, circularity!), Đó là lý do tại sao' Class.new' hoạt động. –

+0

@ JörgWMittag Tôi không phải là chuyên gia về nội bộ của Ruby, nhưng tài liệu cho thấy mới là cả lớp và phương thức thể hiện của Lớp, nếu tôi nhớ chính xác. –

+0

Thực ra, đó là tài liệu cho 'Khởi tạo # lớp '. RDoc chỉ * hiển thị * nó như là tài liệu cho 'Class :: new'. Nó thực hiện điều này cho các lớp * all *, vì đó là cách bạn thường sử dụng * phương thức 'initialize'. Bạn không thực sự gọi nó, bạn có 'new' gọi nó cho bạn. Nếu bạn nhìn vào mã nguồn, bạn có thể thấy rằng khối tài liệu nằm ở trên hàm 'rb_class_initialize' tương ứng với phương thức' Class # initialize'. –

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