lostisland / faraday

Simple, but flexible HTTP client library, with support for multiple backends.

Home Page:https://lostisland.github.io/faraday

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lots of "warning: method redefined; discarding old" printed during testing

sarna opened this issue · comments

commented

Basic Info

  • Faraday Version: 2.7.5
  • Ruby Version: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]

Issue description

With warnings enabled (eg during testing), there are several lines printed with "warning: method redefined; discarding old" warnings.

Steps to reproduce

$ cat Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

gem "faraday"
$ bundle install
Using bundler 2.4.7
Using faraday-net_http 3.0.2
Using ruby2_keywords 0.0.5
Using faraday 2.7.5
Bundle complete! 1 Gemfile dependency, 4 gems now installed.
Bundled gems are installed into `./vendor/bundle`
$ bundle exec irb -W
irb(main):001:0> require "faraday"
/Users/sarna/Developer/ruby/test-faraday/vendor/bundle/ruby/3.2.0/gems/faraday-2.7.5/lib/faraday/options.rb:177: warning: method redefined; discarding old user
/Users/sarna/Developer/ruby/test-faraday/vendor/bundle/ruby/3.2.0/gems/faraday-2.7.5/lib/faraday/options.rb:177: warning: method redefined; discarding old password
/Users/sarna/Developer/ruby/test-faraday/vendor/bundle/ruby/3.2.0/gems/faraday-2.7.5/lib/faraday/options.rb:177: warning: method redefined; discarding old request
/Users/sarna/Developer/ruby/test-faraday/vendor/bundle/ruby/3.2.0/gems/faraday-2.7.5/lib/faraday/options.rb:177: warning: method redefined; discarding old ssl
/Users/sarna/Developer/ruby/test-faraday/vendor/bundle/ruby/3.2.0/gems/faraday-2.7.5/lib/faraday/options.rb:177: warning: method redefined; discarding old builder_class
/Users/sarna/Developer/ruby/test-faraday/vendor/bundle/ruby/3.2.0/gems/faraday-2.7.5/lib/faraday/request.rb:48: warning: method redefined; discarding old params=
/Users/sarna/Developer/ruby/test-faraday/vendor/bundle/ruby/3.2.0/gems/faraday-2.7.5/lib/faraday/request.rb:59: warning: method redefined; discarding old headers=
/Users/sarna/Developer/ruby/test-faraday/vendor/bundle/ruby/3.2.0/gems/faraday-2.7.5/lib/faraday/request/instrumentation.rb:10: warning: method redefined; discarding old name
/Users/sarna/Developer/ruby/test-faraday/vendor/bundle/ruby/3.2.0/gems/faraday-2.7.5/lib/faraday/request/instrumentation.rb:15: warning: method redefined; discarding old instrumenter
=> true

I'm also seeing this in Faraday 2.7.5 and not in 2.7.4.

commented

This is probably a side-effect of #1489 and #1491 (cc @bdewater).
The warnings don't hurt, but I'd prefer them to go away as well if possible.

I don't like that memoized stuff going on in there and I'm not sure I fully understand why we need it, I'll need some time to look into this 👀

This is caused by defining methods with the same name as Struct members.

cat test.rb
X = Struct.new(:a, :b) do
  def a
    :other
  end
end

X.new(1, 2).a # => :otherruby -W test.rb
test.rb:2: warning: method redefined; discarding old a

Before #1489, the above X was defined by inheriting from Struct.new(:a, :b). I'm not sure about Ruby's internal implementation, but I guess the difference between them is the timing of the method definition. Previously, a redefined method was declared as a method of the subclass, which is just a normal overriding.

# This case just overrides the method defined by the parent class.
class X < Struct.new(:a, :b)
  def a
  end
end

# NOTE: The above code is the same as the below.
TMP = Struct.new(:a, :b)
class X < TMP
  def a
  end
end

In the latest code, redefinition occurs during the setup of Struct. This means that defining methods from Struct members as well as custom methods within a block of .new is happening at the same time.

X = Struct.new(:a, :b) do
  def a
  end
end

# Defining the method within the block seems to be the same as the below.
class X
  def a
  end

  def a
  end
end

If possible, it might be the best to avoid defining the same name as Struct members (e.g., user should be renamed). However, such methods might be used by other plugins or applications, so another approach would be required.

I've proposed a fix in #1506 if you all want to take a look.

commented

Thank you @yykamei for the eye-opening explanation and @mattbrictson for providing a fix 🙇

commented

Thank you all ❤️