From: merch-redmine@...
Date: 2021-08-07T16:24:07+00:00
Subject: [ruby-core:104826] [Ruby master Bug#15790] Strange interaction between autoload and $LOADED_FEATURES

Issue #15790 has been updated by jeremyevans0 (Jeremy Evans).


jeremyevans0 (Jeremy Evans) wrote in #note-6:
> I updated the pull request to remove the constant instead of just deleting the autoload. If it passes CI, I'm fine with that approach.

Removing the constant breaks 4 specs:

```
ruby 3.1.0dev (2021-08-06T20:59:12Z autoload-delete-af.. 63f803ae45) [x86_64-openbsd6.9]
                                                                                             
1)
Module#autoload does not remove the constant from Module#constants if the loaded file does not define it, but leaves it as 'undefined' FAILED
Expected ModuleSpecs::Autoload to have constant 'O' but it does not
/home/jeremy/tmp/ruby/spec/ruby/core/module/autoload_spec.rb:455:in `block (2 levels) in <top (required)>'
/home/jeremy/tmp/ruby/spec/ruby/core/module/autoload_spec.rb:34:in `<top (required)>'
                                                                                             
2)
Module#autoload after autoloading searches for the constant like the original lookup in lexical scopes if declared in parent and defined in current FAILED
Expected ModuleSpecs::Autoload to have constant 'DeclaredInParentDefinedInCurrent'
but it does not
/home/jeremy/tmp/ruby/spec/ruby/core/module/autoload_spec.rb:557:in `<module:Autoload>'
/home/jeremy/tmp/ruby/spec/ruby/core/module/autoload_spec.rb:541:in `block (3 levels) in <top (required)>'
/home/jeremy/tmp/ruby/spec/ruby/core/module/autoload_spec.rb:34:in `<top (required)>'
                                                                                             
3)
Module#autoload after autoloading searches for the constant like the original lookup and fails when finding the undefined autoload constant in the current scope when declared in current and defined in parent FAILED
Expected NameError
but no exception was raised (:declared_in_current_defined_in_parent was returned)
/home/jeremy/tmp/ruby/spec/ruby/core/module/autoload_spec.rb:573:in `<class:LexicalScope>'
/home/jeremy/tmp/ruby/spec/ruby/core/module/autoload_spec.rb:571:in `<module:Autoload>'
/home/jeremy/tmp/ruby/spec/ruby/core/module/autoload_spec.rb:566:in `block (3 levels) in <top (required)>'
/home/jeremy/tmp/ruby/spec/ruby/core/module/autoload_spec.rb:34:in `<top (required)>'

4)
Module#const_set when overwriting an existing constant does not warn if the previous value was undefined FAILED
Expected #<Module:0x0000061748b95cc0> to have constant 'Foo' but it does not
/home/jeremy/tmp/ruby/spec/ruby/core/module/const_set_spec.rb:112:in `block (3 levels) in <top (required)>'
/home/jeremy/tmp/ruby/spec/ruby/core/module/const_set_spec.rb:4:in `<top (required)>'
```

I pushed a commit to update the specs.  Do we consider these specs to be desired behavior or just implementation details?  Personally, I strongly dislike having specs for implementation details.

----------------------------------------
Bug #15790: Strange interaction between autoload and $LOADED_FEATURES
https://bugs.ruby-lang.org/issues/15790#change-93168

* Author: fxn (Xavier Noria)
* Status: Open
* Priority: Normal
* ruby -v: ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-darwin18]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN
----------------------------------------
If an autoload fails and we remove its associated file from `$LOADED_FEATURES`, the autoload is back:

```
$ cat x.rb
Y = 1 # should be X, emulates a typo

$ cat test.rb
def au
  Object.autoload?(:X).inspect
end

x_rb = File.realpath("x.rb")
autoload :X, x_rb

puts "before failed autoload autoload path is #{au}"

X rescue nil

puts "after failed autoload autoload path is #{au}"

$LOADED_FEATURES.delete(x_rb)

puts "after $LOADED_FEATURES deletion autoload path is #{au}"
```

The output is

```
$ ruby -v test.rb
ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-darwin18]
before failed autoload autoload path is "/Users/fxn/tmp/x.rb"
after failed autoload autoload path is nil
after $LOADED_FEATURES deletion autoload path is "/Users/fxn/tmp/x.rb"
```

See? Last line would be expected to print a `nil` autoload path.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>