Skip to content

Add annotation for __dir__ - #3181

Merged
ksss merged 1 commit into
ruby:masterfrom
ksss:kernel-__dir__
Sep 29, 2026
Merged

ksss merged 1 commit into
ruby:masterfrom
ksss:kernel-__dir__

Conversation

@ksss

@ksss ksss commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Add %a{implicitly-returns-nil} to Kernel#__dir__ and change its return type from String? to String.

__dir__ returns nil only when the caller has no file path, which in practice means a string eval without a file name:

eval("__dir__")                  # => nil
binding.eval("__dir__")          # => nil
Object.class_eval("__dir__")     # => nil
eval("__dir__", nil, "/tmp/x.rb") # => "/tmp"
ERB.new("<%= __dir__ %>").result # => "."

In ordinary code, i.e. in a file, it is always a String. The same trade-off is already made for Module#name, Exception#backtrace, Array#first, etc.

Why

__dir__ is almost always used to build a path relative to the current file. The path-taking methods do not accept nil, so String? forces every caller to handle a case that does not occur in that usage:

# File.join: (*path) -> String
# File.expand_path: (path file_name, ?path dir_string) -> String
config = File.read(File.join(__dir__, "config.yml"))
Dir.glob(File.join(__dir__, "fixtures", "*.json"))
File.expand_path("../lib", __dir__)

With String? each of these is a type error and needs __dir__ or raise / __dir__.to_s-style workarounds. With this change they type-check as written.

The nil case is still covered by test___dir__ (assert_equal nil, eval('__dir__')), and RBS::Test skips the return-type check for nil thanks to the annotation.

Notes

  • __method__ / __callee__ are left as Symbol? on purpose.

🤖 Generated with Claude Code

@ksss
ksss added this pull request to the merge queue Sep 29, 2026
Merged via the queue into ruby:master with commit 1796bcb Sep 29, 2026
24 checks passed
@ksss
ksss deleted the kernel-__dir__ branch September 29, 2026 06:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant