mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Add an optional inherit
argument to Module#autoload?
[Feature #15777] Closes: https://github.com/ruby/ruby/pull/2173
This commit is contained in:
parent
887163beb8
commit
fb85a42860
7 changed files with 63 additions and 9 deletions
7
NEWS
7
NEWS
|
@ -123,6 +123,13 @@ Integer::
|
|||
0b01001100[2...6] #=> 0b0011
|
||||
^^^^
|
||||
|
||||
Module::
|
||||
|
||||
Modified method::
|
||||
|
||||
* Module#autoload? now takes an +inherit+ optional argument, like as
|
||||
Module#const_defined?. [Feature #15777]
|
||||
|
||||
Regexp / String::
|
||||
|
||||
* Update Unicode version and Emoji version from 11.0.0 to
|
||||
|
|
|
@ -2200,6 +2200,7 @@ VALUE rb_search_class_path(VALUE);
|
|||
VALUE rb_attr_delete(VALUE, ID);
|
||||
VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
|
||||
void rb_autoload_str(VALUE mod, ID id, VALUE file);
|
||||
VALUE rb_autoload_at_p(VALUE, ID, VALUE);
|
||||
void rb_deprecate_constant(VALUE mod, const char *name);
|
||||
NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE));
|
||||
rb_gvar_getter_t *rb_gvar_getter_function_of(const struct rb_global_entry *);
|
||||
|
|
35
load.c
35
load.c
|
@ -1142,25 +1142,42 @@ rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* mod.autoload?(name) -> String or nil
|
||||
* mod.autoload?(name, inherit=true) -> String or nil
|
||||
*
|
||||
* Returns _filename_ to be loaded if _name_ is registered as
|
||||
* +autoload+ in the namespace of _mod_.
|
||||
* +autoload+ in the namespace of _mod_ or one of its ancestors.
|
||||
*
|
||||
* module A
|
||||
* end
|
||||
* A.autoload(:B, "b")
|
||||
* A.autoload?(:B) #=> "b"
|
||||
*
|
||||
* If +inherit+ is false, the lookup only checks the autoloads in the receiver:
|
||||
*
|
||||
* class A
|
||||
* autoload :CONST, "const.rb"
|
||||
* end
|
||||
*
|
||||
* class B < A
|
||||
* end
|
||||
*
|
||||
* B.autoload?(:CONST) #=> "const.rb", found in A (ancestor)
|
||||
* B.autoload?(:CONST, false) #=> nil, not found in B itself
|
||||
*
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
rb_mod_autoload_p(VALUE mod, VALUE sym)
|
||||
rb_mod_autoload_p(int argc, VALUE *argv, VALUE mod)
|
||||
{
|
||||
rb_check_arity(argc, 1, 2);
|
||||
VALUE sym = argv[0];
|
||||
VALUE recur = (argc == 1) ? Qtrue : argv[1];
|
||||
|
||||
ID id = rb_check_id(&sym);
|
||||
if (!id) {
|
||||
return Qnil;
|
||||
}
|
||||
return rb_autoload_p(mod, id);
|
||||
return rb_autoload_at_p(mod, id, recur);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1186,7 +1203,7 @@ rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* autoload?(name) -> String or nil
|
||||
* autoload?(name, inherit=true) -> String or nil
|
||||
*
|
||||
* Returns _filename_ to be loaded if _name_ is registered as
|
||||
* +autoload+.
|
||||
|
@ -1196,14 +1213,14 @@ rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
|
|||
*/
|
||||
|
||||
static VALUE
|
||||
rb_f_autoload_p(VALUE obj, VALUE sym)
|
||||
rb_f_autoload_p(int argc, VALUE *argv, VALUE obj)
|
||||
{
|
||||
/* use rb_vm_cbase() as same as rb_f_autoload. */
|
||||
VALUE klass = rb_vm_cbase();
|
||||
if (NIL_P(klass)) {
|
||||
return Qnil;
|
||||
}
|
||||
return rb_mod_autoload_p(klass, sym);
|
||||
return rb_mod_autoload_p(argc, argv, klass);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1233,9 +1250,9 @@ Init_load(void)
|
|||
rb_define_global_function("require", rb_f_require, 1);
|
||||
rb_define_global_function("require_relative", rb_f_require_relative, 1);
|
||||
rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
|
||||
rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
|
||||
rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, -1);
|
||||
rb_define_global_function("autoload", rb_f_autoload, 2);
|
||||
rb_define_global_function("autoload?", rb_f_autoload_p, 1);
|
||||
rb_define_global_function("autoload?", rb_f_autoload_p, -1);
|
||||
|
||||
ruby_dln_librefs = rb_ary_tmp_new(0);
|
||||
rb_gc_register_mark_object(ruby_dln_librefs);
|
||||
|
|
|
@ -11,6 +11,18 @@ describe "Module#autoload?" do
|
|||
it "returns nil if no file has been registered for a constant" do
|
||||
ModuleSpecs::Autoload.autoload?(:Manualload).should be_nil
|
||||
end
|
||||
|
||||
it "returns the name of the file that will be autoloaded if an ancestor defined that autoload" do
|
||||
ModuleSpecs::Autoload::Parent.autoload :AnotherAutoload, "another_autoload.rb"
|
||||
ModuleSpecs::Autoload::Child.autoload?(:AnotherAutoload).should == "another_autoload.rb"
|
||||
end
|
||||
|
||||
ruby_version_is "2.7" do
|
||||
it "returns nil if an ancestor defined that autoload but recursion is disabled" do
|
||||
ModuleSpecs::Autoload::Parent.autoload :AnotherAutoload, "another_autoload.rb"
|
||||
ModuleSpecs::Autoload::Child.autoload?(:AnotherAutoload, false).should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Module#autoload" do
|
||||
|
|
|
@ -386,6 +386,12 @@ module ModuleSpecs
|
|||
end
|
||||
end
|
||||
|
||||
class Parent
|
||||
end
|
||||
|
||||
class Child < Parent
|
||||
end
|
||||
|
||||
module FromThread
|
||||
module A
|
||||
autoload :B, fixture(__FILE__, "autoload_empty.rb")
|
||||
|
|
|
@ -54,6 +54,10 @@ p Foo::Bar
|
|||
assert_equal(true, b.const_defined?(:X))
|
||||
assert_equal(tmpfile, a.autoload?(:X), bug4565)
|
||||
assert_equal(tmpfile, b.autoload?(:X), bug4565)
|
||||
assert_equal(tmpfile, a.autoload?(:X, false))
|
||||
assert_equal(tmpfile, a.autoload?(:X, nil))
|
||||
assert_nil(b.autoload?(:X, false))
|
||||
assert_nil(b.autoload?(:X, nil))
|
||||
assert_equal(true, a.const_defined?("Y"))
|
||||
assert_equal(true, b.const_defined?("Y"))
|
||||
assert_equal(tmpfile2, a.autoload?("Y"))
|
||||
|
|
|
@ -2331,11 +2331,18 @@ rb_autoload_load(VALUE mod, ID id)
|
|||
|
||||
VALUE
|
||||
rb_autoload_p(VALUE mod, ID id)
|
||||
{
|
||||
return rb_autoload_at_p(mod, id, Qtrue);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_autoload_at_p(VALUE mod, ID id, VALUE recur)
|
||||
{
|
||||
VALUE load;
|
||||
struct autoload_data_i *ele;
|
||||
|
||||
while (!autoload_defined_p(mod, id)) {
|
||||
if (!RTEST(recur)) return Qnil;
|
||||
mod = RCLASS_SUPER(mod);
|
||||
if (!mod) return Qnil;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue