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.