Tôi có một mô-đun Foo
, rằng đó là không gian tên cho nhiều lớp như Foo::Bar
, Foo::Baz
v.v.Làm thế nào để có được tất cả các tên lớp trong một không gian tên trong Ruby?
Có cách nào trả về tất cả tên lớp được đặt tên theo Foo
không?
Tôi có một mô-đun Foo
, rằng đó là không gian tên cho nhiều lớp như Foo::Bar
, Foo::Baz
v.v.Làm thế nào để có được tất cả các tên lớp trong một không gian tên trong Ruby?
Có cách nào trả về tất cả tên lớp được đặt tên theo Foo
không?
Foo.constants
trả về tất cả các hằng số trong Foo
. Điều này bao gồm, nhưng không giới hạn, tên lớp. Nếu bạn muốn chỉ tên lớp, bạn có thể sử dụng
Foo.constants.select {|c| Foo.const_get(c).is_a? Class}
Nếu bạn muốn tên lớp và module, bạn có thể sử dụng is_a? Module
thay vì is_a? Class
.
Nếu, thay vì tên của hằng số, bạn muốn các lớp mình, bạn có thể làm điều đó như thế này:
Foo.constants.map(&Foo.method(:const_get)).grep(Class)
I * love * lập trình điểm miễn phí. Haskell của tôi có hiển thị thông qua không? –
Tôi sẽ mua cho bạn một ly bia cho câu trả lời này! –
Làm gì & làm gì? – shredding
này sẽ chỉ trả lại hằng nạp dưới namespace được vì sử dụng ruby một cách tiếp cận tải chậm. Vì vậy, nếu bạn gõ
Foo.constants.select {|c| Foo.const_get(c).is_a? Class}
bạn sẽ nhận được
[]
nhưng sau khi nhập:
Foo::Bar
bạn sẽ nhận được
[:Bar]
Nói tóm lại không có. Tuy nhiên, bạn có thể hiển thị tất cả các lớp đã được tải. Vì vậy, đầu tiên bạn phải tải tất cả classfiles trong không gian tên:
Dir["#{File.dirname(__FILE__)}/lib/foo/*.rb"].each {|file| load file}
sau đó bạn có thể sử dụng một phương pháp như Jörg W Mittag để liệt kê các lớp
Foo.constants.map (& Foo.method (: const_get)). grep (Loại)
Đây là một câu trả lời hay. Đôi khi bạn quên rằng hằng số trong ruby là bất cứ thứ gì _starts_ với số vốn, vì vậy tên lớp là các cá thể không đổi của lớp loại. +1 –
@jcaudle Ruby không * không * các lớp tải lười biếng. Bạn đang nghĩ về Rails. – sepp2k
Đảm bảo bạn tải tất cả các lớp trước: 'Dir [" ứng dụng/mô hình/foo/*. Rb "]. Mỗi {| tệp | load file} ' – espinchi