mercredi 12 juillet 2017

Why does Ruby fail to remove method even though it is clearly defined?

I work on a rather complex Ruby project that has multiple interdependencies. With recent bundle update, I got logging-rails (0.6.0) pulled in, and that's where mystery started. Attempts to load the project failed, and I tracked them down to this line in that newly updated gem failing with an error:

    NameError: method `logger' not defined in ActionView::Base

OK, I thought, so logger methis not defined somehow, let's figure out why. I opened the logging-rails code in editor and added some debug output before problematic line. But after I ran the project again, I got really puzzled with the results it yielded. Namely:

    puts "#{LOGGER_METHOD.inspect} is included: #{ other.instance_methods.include?(LOGGER_METHOD)}"
    => 
    :logger is included: true

    puts other.method(:logger).source_location.inspect
    =>
    ["/CENSORED/.bundle/gems/ruby/2.3.0/gems/actionpack-3.2.22.5/lib/action_view/base.rb", 149]

    puts other.method(:logger).inspect
    =>
    #<Method: ActionView::Base.logger>

And ultimately:

    result = nil
    begin
      ActionView::Base.logger
      result = "success"
    rescue
      result = "failure"
    end
    puts result

    => 
    success

I'm at a total loss now. The method is defined; Ruby knows exactly where; it executes just fine and returns a result; but when it comes to undefining the method, it's suddenly not defined? WTF?..

Aucun commentaire:

Enregistrer un commentaire