From 9bb40386cebc5a4e6e97911df667f6332e2e8627 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 11 May 2026 08:31:19 +0900 Subject: [PATCH] limitations.md: document nested `def` scope in singleton methods mruby places `def` written inside `def self.foo` on the receiver's singleton class (making it a class method of the enclosing class). CRuby places it as an instance method of the lexical enclosing class. This is a long-standing divergence that we've chosen to document rather than change. close #1536 Co-authored-by: Claude --- doc/limitations.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/doc/limitations.md b/doc/limitations.md index 6470f65a2..07789fa88 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -335,3 +335,38 @@ the splat operator (`*obj`). This is a deliberate trade-off: implicit conversion forces every coercion site to go through method dispatch and can silently mask type-mismatch bugs. + +## Nested `def` in Singleton-Method Context + +`def` written inside a singleton method (`def self.foo`) is placed +on a different class in mruby than in CRuby. CRuby registers the +inner method as an instance method of the lexical enclosing class. +mruby registers it as a method of the enclosing receiver's +singleton class, which makes it visible as a class method of the +enclosing class. + +```ruby +class SomeClass + def self.class_method + def nested; 'nested!'; end + end +end +SomeClass.class_method +``` + +#### CRuby + +``` +SomeClass.nested # NoMethodError +SomeClass.new.nested # => "nested!" (instance method) +``` + +#### mruby + +``` +SomeClass.nested # => "nested!" (class method) +SomeClass.new.nested # NoMethodError +``` + +Writing nested `def` like this is unusual; this difference rarely +surfaces in practical code.