Skip to content

Instantly share code, notes, and snippets.

@Watson1978
Created February 3, 2012 01:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Watson1978/1727088 to your computer and use it in GitHub Desktop.
Save Watson1978/1727088 to your computer and use it in GitHub Desktop.
diff --git a/load.c b/load.c
index b070a120ac25cc07bcca478f8b584f885c593566..d53e06ef5e243ac5577756285997e051314248c8 100644
--- a/load.c
+++ b/load.c
@@ -298,6 +298,23 @@ rb_f_require_imp(VALUE obj, SEL sel, VALUE fname)
return rb_f_require(obj, fname);
}
+VALUE
+rb_f_require_relative(VALUE obj, VALUE fname)
+{
+ VALUE rb_current_realfilepath(void);
+ VALUE base = rb_current_realfilepath();
+ if (NIL_P(base)) {
+ rb_raise(rb_eLoadError, "cannot infer basepath");
+ }
+ base = rb_file_dirname(base);
+ return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
+}
+
+VALUE
+rb_f_require_relative_imp(VALUE obj, SEL sel, VALUE fname)
+{
+ return rb_f_require_relative(obj, fname);
+}
#if !defined(MACRUBY_STATIC)
static bool
@@ -570,6 +587,7 @@ Init_load()
rb_objc_define_module_function(rb_mKernel, "load", rb_f_load, -1);
rb_objc_define_module_function(rb_mKernel, "require", rb_f_require_imp, 1);
+ rb_objc_define_module_function(rb_mKernel, "require_relative", rb_f_require_relative_imp, 1);
rb_objc_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
rb_objc_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
rb_objc_define_module_function(rb_mKernel, "autoload", rb_f_autoload, 2);
diff --git a/vm.cpp b/vm.cpp
index af12f8696ce3454c82744f4ca1943016b47fef8b..140ef94dbe45115565deac7573ef568149b8a77b 100644
--- a/vm.cpp
+++ b/vm.cpp
@@ -3883,6 +3883,28 @@ rb_vm_backtrace(int skip)
return ary;
}
+extern VALUE rb_progname;
+
+extern "C"
+VALUE
+rb_current_realfilepath(void)
+{
+ void *callstack[10];
+ int callstack_n = backtrace(callstack, 10);
+ char path[PATH_MAX];
+ unsigned int interpreter_frame_idx = 0;
+
+ for (int i = 0; i < callstack_n; i++) {
+ path[0] = '\0';
+ GET_CORE()->symbolize_call_address(callstack[i], path, sizeof path,
+ NULL, NULL, 0, &interpreter_frame_idx);
+ if (path[0] != '\0' && path[0] != '-') { // ignore '-e'
+ return rb_str_new_cstr(path);
+ }
+ }
+ return rb_progname;
+}
+
extern "C"
unsigned char
rb_vm_is_eh_active(int argc, ...)
@jballanc
Copy link

jballanc commented Feb 4, 2012

You should submit this as a pull request...I'd like to test it against the specs and see how close it comes (but it looks good!)... :)

@Watson1978
Copy link
Author

Thank you, @jballanc. I will send a pull request soon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment