Project

General

Profile

Bug #12370

require 'mkmf' changes Object#respond_to? behaviour

Added by dsferreira (Daniel Ferreira) almost 4 years ago. Updated almost 4 years ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:75455]

Description

Replication steps:

$ irb
> RUBY_VERSION
=> '2.3.0'
> require 'yaml'
> YAML.public_method_defined?(:configuration)
=> false
> YAML.respond_to?(:configuration)
=> false
> require 'mkmf'
> YAML.public_method_defined?(:configuration)
=> false
> YAML.respond_to?(:configuration)
=> true
Object.constants do |constant|
  constant.respond_to?(:configuration) ==> true
end

--Also there is a different behaviour for core classes over library or gem classes and/or modules under Object namespace.--
Wrong: It is a difference between modules and classes which is fine!
See below on update #8.

The changed behaviour is triggered by:

mkmf.rb:2718 =>

include MakeMakefile

Updated by nobu (Nobuyoshi Nakada) almost 4 years ago

The behavior of Object#respond_to? isn't changed.
Simply mkmf.rb defines configuration method.

$ ruby -rmkmf -e 'p method(:configuration)'
#<Method: Object(MakeMakefile)#configuration>

Just do not mix mkmf.rb unnecessarily, it's only for extconf.rb.

Updated by dsferreira (Daniel Ferreira) almost 4 years ago

Hi Nobu.

I discovered due to this bug in capybara-screenshot gem: [[[https://github.com/mattheworiordan/capybara-screenshot/issues/162]]]

And your right. I also think they should not use

require 'mkmf'

But when I say that Object#respond_to? behaviour was changed it is because of this:

> YAML.respond_to?(:configuration) 
=> true
> YAML.public_method_defined?(:configuration)
=> false

When the definition of Object#respond_to? is that it will be true if public method exists.
So the behaviour is different for some reason.
For me that is a bug or we need to update the definition of the method itself.
Do you agree with me?

Updated by nobu (Nobuyoshi Nakada) almost 4 years ago

  • Status changed from Open to Closed

Module#public_method_defined? is for instance methods.
Object#respond_to? is for its own methods.
They have no relationship.

Updated by dsferreira (Daniel Ferreira) almost 4 years ago

Understood.
So what really makes sense to do is something like this:

$ irb
> require 'mkmf'
> YAML.respond_to?(:configuration)
 => true
> YAML.public_methods.select {|m| m.to_s == 'configuration' }
 => [:configuration]

Updated by dsferreira (Daniel Ferreira) almost 4 years ago

In this situation we have Module#public_method_defined? returning different things for classes and modules which makes sense from its definition where it gets all ancestors when called in a class.
Ex:

$ irb
> require 'mkmf'
> String.respond_to?(:configuration)
 => true
> String.public_method_defined?(:configuration)
 => true
> Enumerable.respond_to?(:configuration)
 => true
> Enumerable.public_method_defined?(:configuration)
 => false

Updated by usa (Usaku NAKAMURA) almost 4 years ago

  • Status changed from Closed to Rejected

Also available in: Atom PDF