2010-11-18 8 views

Trả lời

10

Object#extendcó công khai, nếu không bạn sẽ không thể sử dụng. Sau khi tất cả, mục đích của nó là để trộn trong một mô-đun vào một đối tượng, vì vậy bạn thường gọi nó là obj.extend(Foo), mà không phải là có thể với các phương pháp riêng tư.

Module#include thường chỉ được sử dụng bên trong một cơ thể mô-đun như vậy:

class Bar 
    include Foo 
end 

Tức là nó thường được gọi là không có người nhận, vì vậy nó không phải là công khai. Tất nhiên, nó không là riêng tư.

tôi đoán là lý do tại sao nó là tin là nó xâm lấn hơn, bởi vì nó thay đổi hành vi của mỗi thể hiện của Bar, trong khi Object#extend chỉ thay đổi một đối tượng duy nhất. Do đó, Module#include có ý nghĩa "nguy hiểm hơn" và do đó được đặt ở chế độ riêng tư.

Tôi không biết đó có phải là lý do thực tế hay không, nhưng nó phù hợp với các phương pháp tương tự khác như Module#define_method.

+0

Nó không * có *. Bạn sẽ có thể sử dụng nó nếu nó là private: 'obj.send (: extend, Foo)', 'obj.instance_eval {extend Foo}', không bao gồm trường hợp cho các module 'class Bar; mở rộng Foo; end' –

+0

@ Marc-AndréLafortune: Hoặc 'lớp << obj; mở rộng Foo; cuối cùng, tất nhiên. Như tôi đã nói, nó chỉ là một phỏng đoán. –

+0

Tôi đã trả lời câu đầu tiên của bạn "' Object # extend' phải được công khai, nếu không bạn sẽ không thể sử dụng nó. " –

1

Để có thể chạy Foo.include(Bar) tại bất kỳ thời điểm nào, rất có thể sẽ là nguồn gốc của các lỗi rất khó chịu.

1

Bổ sung câu trả lời Jörg W Mittag của, Object # mở rộng cũng có thể được sử dụng để bao gồm các phương pháp dụ mô-đun để được sử dụng ở mức lớp (mà cũng sẽ có sẵn cho tất cả các trường của lớp đó):

module Foo 
    def bar (baz) 
    end 
end 

class Qux 
    extend Foo 

    bar 'asdf' 
end