2012-02-10 27 views
24

Có cách nào để tắt warning: already initialized constant khi tải các tệp cụ thể không?Cách tắt cảnh báo để xác định lại một hằng số khi tải tệp

+3

Việc sửa mã có thực sự nằm ngoài câu hỏi không? – sarnold

+1

Cảnh báo thường chỉ ra các lỗi ** không gây tử vong ** và phải được khắc phục. Trong trường hợp này bạn rất có thể có một vấn đề thực sự cần được sửa. –

+1

bạn đã khởi tạo biến nhiều lần. –

Trả lời

5

Để ngăn chặn cảnh báo, sử dụng đoạn mã sau ở phía trên cùng của kịch bản:

$VERBOSE = nil 
12

Câu trả lời được chấp nhận cho this question hữu ích. Tôi nhìn vào nguồn Rails để có được những điều sau đây. Trước và sau khi tải tệp, tôi có thể chèn các dòng sau:

# Supress warning messages. 
original_verbose, $VERBOSE = $VERBOSE, nil 
    load(file_in_question) 
# Activate warning messages again. 
$VERBOSE = original_verbose 
+0

hoạt động. Tôi có lẽ nên viết một wrapper cho nó. – Dorian

39

Giải pháp cho vấn đề của bạn tùy thuộc vào nguyên nhân gây ra sự cố.

1 - Bạn đang thay đổi giá trị của hằng số được đặt trước một nơi nào đó trong mã của bạn hoặc đang cố xác định hằng số có cùng tên với lớp hoặc mô-đun hiện có. Giải pháp: không sử dụng hằng số nếu bạn biết trước rằng giá trị của hằng số sẽ thay đổi; không định nghĩa các hằng số có cùng tên với lớp/mô-đun.

2 - Bạn đang ở trong tình huống mà bạn muốn xác định lại hằng số vì lý do chính đáng mà không nhận được cảnh báo. Có hai lựa chọn.

Trước tiên, bạn có thể undefine hằng trước khi xác định lại nó (điều này đòi hỏi một phương pháp helper, vì remove_const là một chức năng riêng):

Object.module_eval do 
    # Unset a constant without private access. 
    def self.const_unset(const) 
    self.instance_eval { remove_const(const) } 
    end 
end 

Hoặc, bạn chỉ có thể nói với người phiên dịch Ruby để im lặng (điều này ngăn chặn tất cả cảnh báo):

# Runs a block of code without warnings. 
def silence_warnings(&block) 
    warn_level = $VERBOSE 
    $VERBOSE = nil 
    result = block.call 
    $VERBOSE = warn_level 
    result 
end 

3 - bạn đang cần một thư viện bên ngoài mà định nghĩa một lớp/mô-đun có cuộc đụng độ với một hằng số mới hoặc lớp/mô-đun bạn đang tạo tên. Giải pháp: bọc mã của bạn bên trong một không gian tên mô-đun cấp cao nhất để ngăn chặn xung đột tên.

class SomeClass; end 
module SomeModule 
    SomeClass = '...' 
end 

4 - Tương tự như trên, nhưng bạn hoàn toàn cần xác định một lớp có cùng tên với lớp của gem/library. Giải pháp: bạn có thể gán tên lớp của thư viện cho một biến, và sau đó rõ ràng nó cho sử dụng sau này của bạn:

require 'clashing_library' 
some_class_alias = SomeClass 
SomeClass = nil 
# You can now define your own class: 
class SomeClass; end 
# Or your own constant: 
SomeClass = 'foo' 
15

Hãy thử cách này:

Kernel::silence_warnings { MY_CONSTANT = 'my value '} 
+3

Phương pháp này không tồn tại với Ruby 2.0.0. – bfontaine

+5

Đó là một phần của đường ray: http://api.rubyonrails.org/classes/Kernel.html#method-i-silence_warnings – stackdump

+2

Giải pháp tuyệt vời, Đó là một phần của đường ray, nhưng bạn chỉ có thể nhập 2 phương thức 'silence_warnings' và' with_warnings' trong một tệp bạn chọn và vá 'Kernel' với nó. – Benj

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