Comments (10)
Can you change your example to have some method(s) defined as well so it's possible to reproduce that problem fully?
from require_all.
In an empty directory create three files
# a.rb
module A
puts "A about to include B"
include ::B
puts "A finished including B"
end
# b.rb
module B
puts "B about to include C"
include ::C
puts "B finished including C"
end
module C
def c_method
puts "I am C"
end
end
And then a fourth file called run.rb
# run.rb
require 'require_all'
puts "Calling require_all on PWD"
$: << '.'
require 'c'
require 'b'
require 'a'
#require_all '.'
puts "Done with require_all"
puts "A has instance methods which are #{A.instance_methods}"
Initially we'll just do it with require in reverse order from C->A and the output of this will be
Calling require_all on PWD
B about to include C
B finished including C
A about to include B
A finished including B
Done with require_all
A has instance methods which are [:c_method]
Here we see that A when all is said and done has a method on it called c_method
because it included B which includes C which has the method.
However if we change run.rb
to comment out the require statements and go with require_all '.'
the output is now
Calling require_all on PWD
A about to include B
B about to include C
Calling require_all on PWD
A about to include B
A finished including B
B about to include C
B finished including C
Done with require_all
here
A has instance methods which are []
Done with require_all
here
A has instance methods which are []
Not totally sure why it runs it twice but I think that it's require_all retrying after a LoadError or something. But at the end A does not have the method defined on C.
from require_all.
I purposely named the files a, b, and c to show that require_all does this when the files are sorted because it sorts the file list before requiring. This isn't bad but there is a chance this will all work if the file names are sorted the other way. For example if A was named C and visa versa this all works because A has the method and is loaded first.
from require_all.
If we had a handy way of knowing what constants were defined before we attempted to load a file and what constants are defined after the attempted file load, we could remove from memory any new constants if a file fails to load cleanly, yes?
from require_all.
Probably. I guess we should start by creating failing test and then trying
to fix the problem. I'm wondering if there's going to be a big performance
hit when it comes to bigger projects.
Anyway, it's worth to try.
On Tue, Oct 27, 2015 at 1:00 AM, Eric Kessler [email protected]
wrote:
If we had a handy way of knowing what constants were defined before we
attempted to load a file and what constants are defined after the attempted
file load, we could remove from memory any new constants if a file fails to
load cleanly, yes?—
Reply to this email directly or view it on GitHub
#8 (comment).
from require_all.
There's a decent chance of a performance hit, yes, but I would think that the most common use case of this gem are one time calls at startup. I mean, this gem is kind of a 'here's a pile of stuff, please figure it out for me' sort of thing. So we are theoretically dealing with users who aren't super reliant on performance or else they would already be taking the extra care of managing their file requiring on their own.
from require_all.
Waiting for a possible fix/pull request. I do not probably have time to do that so if there's someone willing, I'd happily accept a pull request. Thanks!
from require_all.
I just ran into this myself. Luckily I recall this issue existing, so I didn't waste too much time determining what was wrong and adding at least a little order to how I pull in files. Still, it would be nice if we could get this solved.
from require_all.
Still waiting for a PR. Closing this due to inactivity until then.
from require_all.
This is exactly the sort of issue that is difficult/impossible to fix given the way require_all
currently works, so is why I opened the strict mode PR, to allow the simple addition of any explicit requires needed to ensure dependencies are loaded.
Regarding the earlier suggestion in this issue by @enkessler, ie of tracking which constants are defined before each file is required and unloading newly-added ones in the case of errors, I can see at least three very-hard-to-solve/unsolvable issues with that approach:
- Defining of classes/constants is not the only side-effect of requiring a file - eg what about methods or other state being added to other classes? Or expensive operations that must only happen once, the results of which are memoized in (for example) the singleton class of a class that's defined during the require? It might not be safe to do those operations again
- Indirectly-required constants - what about constants that were loaded as a side-effect of
require_all
requiring the file? ie it would be impossible to tell the difference between constants defined (directly) by the file just required and ones defined in files that were required by the file just required. You'd have to unload (and subsequently reload) all of them - Very expensive - as pointed out above, it would be very expensive to get a list of the (global) set of loaded constants before each file and cause a fair amount of GC pressure as all those objects have to be collected, all for marginal benefit.
from require_all.
Related Issues (14)
- make it cross-platform compatible HOT 4
- Can't handle empty directories HOT 3
- License mismatch HOT 5
- Your NameError logic needs to be more selective HOT 1
- how about '#require_dependency if defined? Rails' ? HOT 3
- Unable to install in application's Gemfile or outside of it HOT 5
- "Could not require ... (uninitialized constant ...)" with 2.0.0 HOT 16
- Trying to use `require_all` with a folder of the same name as the target file fails HOT 2
- How do I load a directory of files relative to the LOAD_PATH? HOT 5
- RequireAll::LoadError: Could not require HOT 1
- License missing from gemspec HOT 2
- require_all does not respect $LOAD_PATH HOT 2
- Handles directories containing glob characters incorrectly. HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from require_all.