2011-11-16 36 views
34

Tôi nhận được cảnh báo này khi tôi chạy rspec:cảnh báo iconv deprecation với ruby ​​1.9.3

 
/gems/activesupport-3.1.0/lib/active_support/dependencies.rb:240:in `block in require': iconv will be deprecated in the future, use String#encode instead. 

Tôi nhận được cảnh báo tương tự với đường ray 3.1.0, 3.1.1, 3.1.2.rc2 phiên bản. Có vẻ như nó liên quan đến đá quý sqlite3, nhưng tôi không chắc chắn. Không có cảnh báo nào có ruby ​​1.9.2

Bất kỳ đề xuất nào về cách giải quyết?

Trả lời

17

Nếu bạn thấy điều này, có thể là không phải Đường ray. Nếu bạn nhìn vào phương pháp xung quanh dòng được đề cập đến trong lỗi bạn đã đăng, bạn sẽ thấy như sau:

def require(file, *) 
    result = false 
    load_dependency(file) { result = super } 
    result 
end 

Tôi không nói đó là mã của bạn, nhất thiết, nhưng tôi chắc chắn rằng đó là không thực sự là dòng trong câu hỏi mà iconv đang được gọi. Trong trường hợp của tôi, tôi thấy rằng mã của dự án của tôi thực sự chứa một tham chiếu đến iconv.

Nếu bạn muốn kiểm tra mã của mình để tham khảo như vậy, hãy thử grep -ir iconv ./ trong thư mục dự án của bạn.

Khi iconv thực sự nằm trong thư viện, bạn có thể khó tìm thấy hơn. Bằng cách tạm thời thay đổi phương thức trên thành:

def require(file, *) 
    result = false 
    puts 
    puts caller.reverse 
    load_dependency(file) { result = super } 
    result 
end 

Sau đó, bạn có thể dễ dàng chạy mã và tìm ra nguyên nhân gốc của cảnh báo.

ruby your/code.rb 2>&1 | grep -B 5 iconv 
+0

Bởi chỉ cần thêm "p gọi" trên một dòng trước dòng load_dependency và nhìn qua đống dấu vết nó trở nên khá dễ dàng để shuffle qua Gemfile của bạn và sửa chữa các quá hạn đá quý. –

+0

Tôi nghĩ rằng cách đơn giản nhất là chỉ cần thêm 'đặt" >>>> # {file.inspect} "' ngay trước 'load_dependency', sau đó bạn có thể xem tải tệp nào gây ra thư. –

8

Thêm này để bắt đầu chương trình của bạn:

oldverb = $VERBOSE; $VERBOSE = nil 
require 'iconv' 
$VERBOSE = oldverb 

và nguyền rủa những người nghĩ rằng đây là một cách chuyên nghiệp để xử lý deprecation.

+3

Tôi không thấy lý do tại sao điều này lại bị giảm giá nhiều. Đây là một cách để im lặng nếu bạn đã biết nhưng không muốn nâng cấp. Nếu bạn đặt điều này trước 'require' khác có thể có thể kéo vào' iconv' trong một số chuỗi 'require' lồng nhau, thì thông báo sẽ không xuất hiện nữa. – Kelvin

+0

Câu trả lời hoàn hảo. Điều này đã giúp tôi trong việc loại bỏ cảnh báo vô dụng này trên một hệ thống mà tôi hoàn toàn không kiểm soát được những viên đá quý đã cài đặt hay bất cứ thứ gì. –

7

Bạn có thể ghim vị trí chính xác của cảnh báo bằng cách tạo ngoại lệ cho ActiveSupport :: Ngừng sử dụng, thay vì chỉ in vào nhật ký. Ở phía trên cùng của ứng dụng.rb:

ActiveSupport::Deprecation.behavior = Proc.new do |message, backtrace| 
    raise message 
end 

Khi bạn đã tìm ra cảnh báo đến từ đâu (bằng cách kiểm tra backtrace đầy đủ), hãy xóa lại.

+0

Tôi nhận được 'hành vi phương pháp undefined = cho ActiveSupport :: Khấu hao: Module (NoMethodError)' - Rails 3.2.3, Ruby 1.9.3-p125 –

+3

rõ ràng nó sử dụng chính tả của Mỹ - "hành vi". – XP84

+1

@ XP84, cảm ơn bạn đã chỉ ra điều đó :) – d11wtq

68

Bạn nhận được thông báo phản đối này khiến thư viện ở một nơi nào đó yêu cầu iconv.

iconv là đá quý được tạo bởi Matz có thể được sử dụng để chuyển đổi chuỗi từ định dạng này sang định dạng khác.

Ví dụ này thường được sử dụng:

Iconv.iconv('UTF-8//IGNORE', 'UTF-8', content) bit này chút ma thuật phải mất một chuỗi UTF-8 mà có thể có ký tự không hợp lệ và chuyển đổi nó vào một hợp chuỗi UTF-8.

Nó đã được quyết định rằng trong Ruby 1.9.3 chúng ta không nên sử dụng iconv nữa và thay vào đó sử dụng được xây dựng trong String#encode. encode mạnh mẽ hơn và cho phép bạn linh hoạt hơn.

Lý thuyết này là ví dụ trên có thể được thay thế bằng:

string.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => "?")

Trên thực tế có vẻ như đây là imperfect.

cũng Điều này dẫn đến một câu chuyện ít hơn dễ dàng cho người sáng tạo đá quý có nhu cầu hỗ trợ 1.8:

content = RUBY_VERSION.to_f < 1.9 ? 
    Iconv.iconv('UTF-8//IGNORE', 'UTF-8', "content") : 
    "#{content}".encode(Encoding::UTF_8, :invalid => :replace, :undef => :replace, :replace => '') 

Vì vậy, bạn có một viên ngọc ở đâu đó rằng đang yêu cầu iconv, để tìm thấy nó:

Giả sử thông báo lỗi của bạn là: /gems/activesupport-3.1.0/lib/active_support/dependencies.rb:240

mở lên /gems/activesupport-3.1.0/lib/active_support/dependencies.rb on line 240:

Thêm dòng:

p caller if file =~ /iconv/ 

(chỉ sau: load_dependency(file) { result = super })

Bạn sẽ nhận được một chất béo vết đống lớn:

 
rake --tasks 
/home/sam/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:251:in `block in require': iconv will be deprecated in the future, use String#encode instead. 
["/home/sam/.rvm/gems/ruby-1.9.3-p125/gems/calais-0.0.13/lib/calais.rb:5:in `'", 
.. more omitted .. 

này nói với tôi nó là calais đá quý. Nhìn qua các yêu cầu kéo, tôi am not the first. Kéo không được kéo mạnh.


Tùy thuộc vào đá quý, có thể có phiên bản nâng cấp không có lỗi này, vì vậy tôi khuyên bạn nên nâng cấp đá quý trước. Nếu bạn không may mắn bạn có thể bị mắc kẹt với nhiệm vụ bất hạnh của forking một viên ngọc để thoát khỏi điều này (nếu ví dụ yêu cầu kéo của bạn để sửa chữa nó mòn mỏi)

+1

Cảm ơn, điều này đã giúp tôi. Tôi đã sử dụng ActiveSupport 3.2.9 và phải sử dụng: 'p caller nếu file.to_s = ~/iconv /' (tập tin bây giờ là [Pathname] (http://www.ruby-doc.org/stdlib-1.9. 3/libdoc/pathname/rdoc/Pathname.html) thay vì một String.) –

+1

Đây là một câu trả lời tuyệt vời! Tôi đã làm theo các bước và tìm thấy những gì đá quý đã gây ra các vấn đề trong ứng dụng của tôi. Đó là một sự xấu hổ áp phích ban đầu đã không chấp nhận câu trả lời này ... hoặc bất kỳ những người khác cho rằng vấn đề. – jacklin

+0

Đây là một câu trả lời tuyệt vời và một mô hình cho một câu trả lời SO nên được viết như thế nào. Giải thích rõ ràng, ngắn gọn và dễ làm theo các bước để gỡ lỗi vấn đề. –

0

Để xóa cảnh báo này ...

đi thư mục .rvm của bạn và tìm iconv.c (mỏ đang ở ~/.rvm/src/ruby-1.9.3-p125/ext/iconv/iconv.c)

chỉnh sửa tập tin đó được loại bỏ hoặc nhận xét ra các cuộc gọi đến warn_deprecated() (nên gần phía dưới)

từ thư mục của tập tin đó, hãy chạy ruby extconf.rb sau đó make sau đó make install

Nên làm các trick

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