Project

General

Profile

Feature #11415

autoload with a Proc

Added by matthewd (Matthew Draper) about 4 years ago. Updated almost 4 years ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:70246]

Description

autoload currently allows you to run arbitrary code when a constant is referenced, as long as that code is written to a file.

I propose extending autoload to also accept a Proc in place of the string filename.

Usage:

autoload :Foo, -> { ::Object.const_set :Foo, 42 }
autoload :Bar, -> { require "bar_1"; require "bar_2" }
autoload :Baz, -> { with_special_lock { require "baz" } }

No built-in concurrency protection is provided: if a second thread encounters a constant reference before the first one sets the constant, the second thread will also enter the Proc.

Under simple usage, the proc will still call require at some point -- then require's locking will take effect. A more advanced user can apply their own locking.

I believe this is sufficient to allow the Rails dependency loader to use autoload instead of const_missing, and fix the "nested constants" problem.

The implementation is quite small, and it doesn't seem to make the dangers of autoload any worse than they already are. Hopefully, it can provide an easier place for users to experiment in ways to save autoload by making it more generally safe.

Alternatives

For Rails's purposes, nested constants could also be solved by a missing_constant (or similar) macro:

module Foo; end
module Bar; end

Foo::Bar # => returns ::Bar


module Foo; missing_constant :Bar; end
module Bar

Foo::Bar # => invokes Foo.const_missing(:Bar)

More directly, instead of passing a Proc to autoload, a caller can write the code to a tempfile, and then specify that tempfile's path.


Files

autoload-proc.patch (5.83 KB) autoload-proc.patch matthewd (Matthew Draper), 08/05/2015 02:23 AM

History

Updated by matz (Yukihiro Matsumoto) almost 4 years ago

I hate autoload. autoload is one of things I regret. I'm not positive about enhancing something I hate.
-- matz in https://speakerdeck.com/skade/the-dark-side-of-matz-1

How about using const_missing?

Matz.

Updated by normalperson (Eric Wong) almost 4 years ago

matz@ruby-lang.org wrote:

I hate autoload. autoload is one of things I regret. I'm not positive about enhancing something I hate.
-- matz in https://speakerdeck.com/skade/the-dark-side-of-matz-1

Would you like autoload if Ruby didn't have threads? :)

Anyways, I think autoload is somewhat useful for improving startup
times; but the interaction with threads is currently dangerous.

How about using const_missing?

Using that would be even more fragile, I think.

Also available in: Atom PDF