Project

General

Profile

Bug #22076

Updated by sampokuokkanen (Sampo Kuokkanen) 5 months ago

Filing this to confirm whether defined? should return "method" here (matching the call check), or whether the current nil behavior is intentional. 

 ### Summary 

 `defined?` returns `nil` for a protected method defined in a module, even when the same call succeeds.  
 For a protected method defined in a class, `defined?` and the call agree. 

 ### Reproduction 

 ~~~ruby 
 module Mix 
   def secret; 42; end 
   protected :secret 
 end 

 class A; include Mix; end 

 class B 
   include Mix 
   def call_it(other)      = other.secret 
   def defined_it(other) = defined?(other.secret) 
 end 

 p B.new.call_it(A.new)        # => 42 
 p B.new.defined_it(A.new)     # => nil      (expected "method") 
 ~~~ 

 The class-defined version returns `"method"` for the same shape: 

 ~~~ruby 
 class Base 
   def secret; 42; end 
   protected :secret 
 end 
 class A < Base; end 
 class B < Base 
   def defined_it(other) = defined?(other.secret) 
 end 
 p B.new.defined_it(A.new)     # => "method" 
 ~~~ 

 ### Fix 

 Use `rb_callable_method_entry_with_refinements` and the existing 
 `vm_defined_class_for_protected_call` helper. Patch with test: 
 https://github.com/ruby/ruby/pull/17069 (will update soon) 

 ## Environment 
 - MacOS Tahoe 26.2 
 - Ruby master (HEAD) 
 - ruby 4.0.1 

Back