2016-06-14 19 views
5

Tôi có một mô-đun, có chứa lớp có tên String (trong số những người khác). Tôi cần tra cứu lớp theo tên và quay lại một cách duyên dáng nếu không có lớp học như vậy.Có thể thu hẹp tra cứu hằng số ruby ​​

module Mod1 
    module String 
    end 
end 
Mod1.const_get 'String' 
#⇒ Mod1::String 
Kernel.const_get '::Mod1::String' 
#⇒ Mod1::String 

cho đến giờ, rất tốt. Tôi dự kiến ​​sẽ nhận được NameError khi tôi cố gắng tra cứu lớp không tồn tại, điều đó là tốt. Vấn đề là nếu có một lớp học với tên được đặt tồn tại trong không gian tên toàn cầu, nó đang được trả về:

Mod1.const_get 'Fixnum' 
#⇒ Fixnum < Integer 
Kernel.const_get '::Mod1::Fixnum' 
#⇒ Fixnum < Integer 

tôi hiểu được lý do, nhưng câu hỏi của tôi sẽ là: là có một out-of -phương pháp hộp để tra cứu một hằng số trong không gian tên đã cho?

Bây giờ tôi kiểm tra kết quả với

result.to_s.start_with?(namespace) 

nhưng điều này chắc chắn là không phải là cách để thu hẹp fanciest một tra cứu.

Trả lời

7

Câu trả lời là:

Mod1.const_get 'Fixnum', false 

Đây là doc:

/* 
* call-seq: 
*  mod.const_get(sym, inherit=true) -> obj 
*  mod.const_get(str, inherit=true) -> obj 
* 
* Checks for a constant with the given name in <i>mod</i>. 
* If +inherit+ is set, the lookup will also search 
* the ancestors (and +Object+ if <i>mod</i> is a +Module+). 
* 
* The value of the constant is returned if a definition is found, 
* otherwise a +NameError+ is raised. 
* 
*  Math.const_get(:PI) #=> 3.14159265358979 
* 
* This method will recursively look up constant names if a namespaced 
* class name is provided. For example: 
* 
*  module Foo; class Bar; end end 
*  Object.const_get 'Foo::Bar' 
* 
* The +inherit+ flag is respected on each lookup. For example: 
* 
*  module Foo 
*  class Bar 
*   VAL = 10 
*  end 
* 
*  class Baz < Bar; end 
*  end 
* 
*  Object.const_get 'Foo::Baz::VAL'   # => 10 
*  Object.const_get 'Foo::Baz::VAL', false # => NameError 
* 
* If the argument is not a valid constant name a +NameError+ will be 
* raised with a warning "wrong constant name". 
* 
* Object.const_get 'foobar' #=> NameError: wrong constant name foobar 
* 
*/ 

https://github.com/ruby/ruby/blob/449fbfd4d4ce47be227804c22214fed32a5b0124/object.c#L2027

+1

Perfect, cảm ơn. Lời khuyên hiển nhiên "hãy xem tài liệu phương pháp" hoạt động như bình thường. – mudasobwa

+0

Tôi có thể đề xuất liên kết tới các tài liệu thay vì nguồn MRI không? http://ruby-doc.org/core-2.3.1/Module.html#method-i-const_get –

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