Feature #15230



Added by mame (Yusuke Endoh) about 5 years ago. Updated over 4 years ago.

Target version:


I'd like a feature to know what will be loaded by require(feature) without actual loading.

$ ./local/bin/ruby -e 'p RubyVM.resolve_feature_path("set")'
[:r, "/home/mame/work/ruby/local/lib/ruby/2.6.0/set.rb"]

$ ./local/bin/ruby -e 'p RubyVM.resolve_feature_path("etc")'
[:s, "/home/mame/work/ruby/local/lib/ruby/2.6.0/x86_64-linux/"]

This feature is useful for a static analysis tool of Ruby programs. It might also be useful to check $LOAD_PATH configuration.

I don't think that RubyVM is the best place to have this method, but a good place to experiment the new feature. Kernel#resolve_feature_path looks too aggressive.

diff --git a/load.c b/load.c
index ddde2baf3b..dd609105ee 100644
--- a/load.c
+++ b/load.c
@@ -942,6 +942,26 @@ load_ext(VALUE path)
     return (VALUE)dln_load(RSTRING_PTR(path));
+rb_resolve_feature_path(VALUE klass, VALUE fname)
+    VALUE path;
+    int found;
+    char s[2];
+    fname = rb_get_path_check(fname, 0);
+    path = rb_str_encode_ospath(fname);
+    found = search_required(path, &path, 0);
+    if (!found) {
+        load_failed(fname);
+    }
+    s[0] = found;
+    s[1] = 0;
+    return rb_ary_new_from_args(2, ID2SYM(rb_intern2(s, 1)), path);
  * returns
  *  0: if already loaded (false)
diff --git a/vm.c b/vm.c
index fababaa2ec..2a72d16f47 100644
--- a/vm.c
+++ b/vm.c
@@ -2834,6 +2834,8 @@ static VALUE usage_analysis_operand_stop(VALUE self);
 static VALUE usage_analysis_register_stop(VALUE self);
+VALUE rb_resolve_feature_path(VALUE klass, VALUE fname);
@@ -3140,6 +3142,8 @@ Init_VM(void)
     /* vm_backtrace.c */
+    rb_define_singleton_method(rb_cRubyVM, "resolve_feature_path", rb_resolve_feature_path, 1);

Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #15903: Move RubyVM.resolve_feature_path to Kernel.resolve_feature_pathClosedmatz (Yukihiro Matsumoto)Actions

Updated by Eregon (Benoit Daloze) about 5 years ago

What's the leading one letter Symbol in the return value?
That seems fairly cryptic.

Do you need it? I would expect such a method to return a path, i.e., a String.

Updated by mame (Yusuke Endoh) about 5 years ago

:r means .rb and :s means .so, I guess :-)

It is not absolutely necessary. But it would be somewhat useful for a static analysis tool of Ruby programs because such a tool typically needs to skip .so files.

Updated by Eregon (Benoit Daloze) about 5 years ago

If it's reliable enough (I think it is) to detect native extensions by the file extension (.so, .dylib)
then I think that should be preferred as it would simplify the method's result.

Updated by duerst (Martin Dürst) about 5 years ago

mame (Yusuke Endoh) wrote:

:r means .rb and :s means .so, I guess :-)

If this information is kept, please make it easier to understand. :rb/:so or :'.rb'/:'.so' at a minimum.

Actions #5

Updated by mame (Yusuke Endoh) almost 5 years ago

  • Status changed from Assigned to Closed

Applied in changeset trunk|r66237.

load.c (RubyVM.resolve_feature_path): New method. [Feature #15230]

Updated by znz (Kazuhiro NISHIYAMA) almost 5 years ago

It returns false as path when feature is already loaded.
Is it intentional?

% rbenv exec irb --simple-prompt -r irb/completion
>> RubyVM.resolve_feature_path('set')
=> [:rb, false]

Updated by Eregon (Benoit Daloze) over 4 years ago

@mame (Yusuke Endoh) should the behavior that @znz (Kazuhiro NISHIYAMA) reports be fixed?
resolve_feature_path sounds like it should always resolve a feature, no matter if the feature is loaded or not.

Actions #8

Updated by Eregon (Benoit Daloze) over 4 years ago

  • Related to Feature #15903: Move RubyVM.resolve_feature_path to Kernel.resolve_feature_path added

Updated by mame (Yusuke Endoh) over 4 years ago

Eregon (Benoit Daloze) wrote:

@mame (Yusuke Endoh) should the behavior that @znz (Kazuhiro NISHIYAMA) reports be fixed?

I hear @nobu (Nobuyoshi Nakada) has already fixed the issue. (Thanks!)


Also available in: Atom PDF