2012-07-09 10 views
6

sự khác biệt giữa điều này là gìSự khác nhau giữa các định nghĩa mô-đun lồng nhau và sử dụng :: trong định nghĩa trong ruby ​​là gì?</p> <pre><code>module Outer module Inner class Foo end end end </code></pre> <p>và điều này::

module Outer::Inner 
    class Foo 
    end 
end 

Tôi biết các ví dụ sau này sẽ không hoạt động nếu Outer không được định nghĩa trước đó, nhưng có một số khác biệt khác với thường xuyên phạm vi và tôi có thể tìm thấy mô tả của họ trên SO hoặc trong tài liệu (kể cả cuốn sách Lập trình Ruby)

+0

Tôi nghĩ rằng "class A :: B :: MyClass" làm làm việc, phải không? – davidrac

+0

Có, nó hoạt động, nhưng sự khác biệt giữa 'class A :: B :: MyClass; end' và 'module A; mô-đun B; lớp MyClass; kết thúc; kết thúc; kết thúc; '? –

Trả lời

3

có ít nhất một sự khác biệt - tra cứu liên tục, kiểm tra mã này:

module A 
    CONST = 1 

    module B 
    CONST = 2 

    module C 
     def self.const 
     CONST 
     end 
    end 
    end 
end 

module X 
    module Y 
    CONST = 2 
    end 
end 

module X 
    CONST = 1 

    module Y::Z 
    def self.const 
     CONST 
    end 
    end 
end 

puts A::B::C.const # => 2, CONST value is resolved to A::B::CONST 
puts X::Y::Z.const # => 1, CONST value is resolved to X::CONST 
+0

Vì vậy, nó sử dụng phạm vi từ vựng cho hằng số và "nhảy qua" :: khi đi bộ định nghĩa mô-đun lên, đúng không? –

+0

Tôi không biết chi tiết thuật toán của họ nhưng chắc chắn nó trông giống như vậy. biết rằng điều đó giúp bạn tránh gỡ lỗi địa ngục đôi khi. tôi không biết về bất kỳ sự khác biệt nào khác giữa 2 loại mô-đun/lớp định nghĩa. – keymone

+0

Có, điều này kết hợp với Rails tự động tải có thể dẫn đến một số gỡ lỗi địa ngục :) –

7

Nhờ keymone của answer tôi xây dựng truy vấn Google chính xác và thấy điều này: Module.nesting and constant name resolution in Ruby

Sử dụng :: thay đổi phạm vi liên tục giải quyết

module A 
    module B 
    module C1 
     # This shows modules where ruby will look for constants, in this order 
     Module.nesting # => [A::B::C1, A::B, A] 
    end 
    end 
end 

module A 
    module B::C2 
    # Skipping A::B because of :: 
    Module.nesting # => [A::B::C2, A] 
    end 
end