Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
sarna opened this issue May 26, 2023 · 7 comments · Fixed by #1506
Closed

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

sarna opened this issue May 26, 2023 · 7 comments · Fixed by #1506

Comments

@sarna
Copy link

sarna commented May 26, 2023

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
@nholden
Copy link

nholden commented May 29, 2023

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

@iMacTia
Copy link
Member

iMacTia commented May 30, 2023

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 👀

@yykamei
Copy link
Contributor

yykamei commented May 30, 2023

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

@yykamei
Copy link
Contributor

yykamei commented May 30, 2023

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.

@mattbrictson
Copy link
Contributor

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

@iMacTia
Copy link
Member

iMacTia commented Jun 7, 2023

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

@sarna
Copy link
Author

sarna commented Jun 7, 2023

Thank you all ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants