Project

General

Profile

Actions

Bug #22076

closed

defined? returns nil for protected methods defined in a module even when callable

Bug #22076: defined? returns nil for protected methods defined in a module even when callable

Added by sampokuokkanen (Sampo Kuokkanen) about 10 hours ago. Updated about 9 hours ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [arm64-darwin25]
[ruby-core:125553]

Description

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

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:

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

Environment

  • MacOS Tahoe 26.2
  • Ruby master (HEAD)
  • ruby 4.0.1

Updated by sampokuokkanen (Sampo Kuokkanen) about 10 hours ago Actions #1

  • Description updated (diff)

Updated by sampokuokkanen (Sampo Kuokkanen) about 10 hours ago Actions #2

  • ruby -v set to ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [arm64-darwin25]

Updated by nobu (Nobuyoshi Nakada) about 10 hours ago Actions #3 [ruby-core:125554]

  • Backport changed from 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN to 3.3: REQUIRED, 3.4: REQUIRED, 4.0: REQUIRED

The expectation and the fix seem reasonable both.

Updated by sampokuokkanen (Sampo Kuokkanen) about 9 hours ago Actions #4

  • Status changed from Open to Closed

Applied in changeset git|d1391a000359655f948e16d7f2b0e85890082b5a.


Fix defined? for protected methods defined in a module

me->defined_class is 0 for methods stored on a module, so the
protected visibility check in vm_defined always failed and defined?
returned nil even when the call would succeed.

Use rb_callable_method_entry_with_refinements (where defined_class is
populated) and the same vm_defined_class_for_protected_call helper as
the call path. defined? now agrees with whether the method could
actually be called.

[Bug #22076]

Actions

Also available in: PDF Atom