When upgrading one of our apps from ruby 1.9.3 to ruby 2.1, deprecation warnings started appearing at the beginning of our test runs. While not a huge deal, I like to keep our codebase as tidy as possible, so these warnings must go. I quickly found that these warnings were coming from a change in the openssl library, but finding the code using the deprecated class was more challenging.
$ rspec
Digest::Digest is deprecated; use Digest
Digest::Digest is deprecated; use Digest
Digest::Digest is deprecated; use Digest
......F....
Ruby has a really cool built-in method called Kernel#set_trace_func. It's very powerful, and you're only limited by your imagination as to what you can do with it. In my case, I used it to print a few lines of the call stack whenever the deprecated method gets called. Since the warnings appeared during application startup, I added the following lines to the top of confing/boot.rb to ensure that it was in place before any gems were required.
set_trace_func(Proc.new do |event, filename, line, object_id, binding, klass|
if event == 'c-call' && object_id.to_s == 'warn'
puts "#{klass}##{object_id} #{filename}:#{line}"
puts caller[0,5].join("\n")
end
end)
#set_trace_func
takes a Proc
as an argument then calls that Proc
when any
event happens, like calling a method or raising an exception. This can get very
noisy very fast, so I used a conditional to see just the events I care about.
In this case, I wanted to see the Kernel#warn
method, which is a C method
call, not a ruby method call.
$ rspec
Kernel#warn /Users/jordan/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/openssl/digest.rb:64
/Users/jordan/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/openssl/digest.rb:64:in `initialize'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/right_aws-3.1.0/lib/awsbase/right_awsbase.rb:29:in `new'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/right_aws-3.1.0/lib/awsbase/right_awsbase.rb:29:in `<class:AwsUtils>'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/right_aws-3.1.0/lib/awsbase/right_awsbase.rb:28:in `<module:RightAws>'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/right_aws-3.1.0/lib/awsbase/right_awsbase.rb:25:in `<top (required)>'
Digest::Digest is deprecated; use Digest
Kernel#warn /Users/jordan/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/openssl/digest.rb:64
/Users/jordan/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/openssl/digest.rb:64:in `initialize'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/right_aws-3.1.0/lib/awsbase/right_awsbase.rb:32:in `new'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/right_aws-3.1.0/lib/awsbase/right_awsbase.rb:32:in `<class:AwsUtils>'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/right_aws-3.1.0/lib/awsbase/right_awsbase.rb:28:in `<module:RightAws>'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/right_aws-3.1.0/lib/awsbase/right_awsbase.rb:25:in `<top (required)>'
Digest::Digest is deprecated; use Digest
Kernel#warn /Users/jordan/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/openssl/digest.rb:64
/Users/jordan/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/openssl/digest.rb:64:in `initialize'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/fog-1.8.0/lib/fog/cloudstack.rb:11:in `new'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/fog-1.8.0/lib/fog/cloudstack.rb:11:in `<module:Cloudstack>'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/fog-1.8.0/lib/fog/cloudstack.rb:5:in `<module:Fog>'
/Users/jordan/.rvm/gems/ruby-2.1.1/gems/fog-1.8.0/lib/fog/cloudstack.rb:4:in `<top (required)>'
Digest::Digest is deprecated; use Digest
......F....
Now I can clearly see where the deprecation warnings are coming from. We are in
the process of migrating from the
right_aws gem to the
fog gem, so the first two deprecation warnings will go away
when we complete that effort. As for the deprecation warning coming from the
fog gem, we were able to upgrade fog and require fog/aws
instead of fog
since we don't use the cloudstack provider.
One last thing, remember to remove the #set_trace_func
code before you ship!
It will definitely impair the performance of your app if you forget.