[#69084] [Ruby trunk - Feature #11124] [Open] [PATCH] lib/*: use monotonic clock for timeouts — normalperson@...
Issue #11124 has been reported by Eric Wong.
5 messages
2015/05/06
[#69138] [Ruby trunk - Feature #11136] [PATCH] webrick: avoid fcntl module — nobu@...
Issue #11136 has been updated by Nobuyoshi Nakada.
3 messages
2015/05/12
[#69160] [Ruby trunk - Feature #11146] [PATCH] variable.c: initialize generic_iv_tbl at start — nobu@...
Issue #11146 has been updated by Nobuyoshi Nakada.
4 messages
2015/05/13
[#69175] Re: [Ruby trunk - Feature #11146] [PATCH] variable.c: initialize generic_iv_tbl at start
— Eric Wong <normalperson@...>
2015/05/13
nobu@ruby-lang.org wrote:
[ruby-core:69163] [Ruby trunk - Feature #11148] Add a way to require files, but not raise an exception when the file isn't found
From:
eregontp@...
Date:
2015-05-13 11:14:09 UTC
List:
ruby-core #69163
Issue #11148 has been updated by Benoit Daloze.
Why is that exception problematic?
For performance (the cost of the search is already large I suppose)
or to only catch the LoadError from require and not accidentally from somewhere else? (this could potentially affect compatibility)
----------------------------------------
Feature #11148: Add a way to require files, but not raise an exception when the file isn't found
https://bugs.ruby-lang.org/issues/11148#change-52421
* Author: Aaron Patterson
* Status: Open
* Priority: Normal
* Assignee:
----------------------------------------
Hi,
I'm trying to make is so that RubyGems doesn't need to put directories on $LOAD_PATH (which is why I submitted Feature #11140). I would like the `require` implemented in RubyGems to look up the file from a cache generated when the gem is installed, then pass a full file path to `require`.
The problem is that the user may have manipulated the load path somehow, and RubyGems needs to detect if the file is in the load path. Today, the algorithm inside RubyGems looks something like this:
~~~ruby
def require file
if file_is_from_a_default_gem?(file) # this is so you can install new versions of default gems
add_default_gem_to_loadpath
end
real_require file
rescue LoadError
gem = find_gem_that_contains_file(file)
add_gem_to_loadpath gem
real_require file
end
~~~
Instead of adding the directory to the load path, I would like to look up the full file path from a cache that is generated when the gem is installed. If we had a cache, that means the new implementation would look like this:
~~~ruby
def require file
if file_is_from_a_default_gem?(file) # this is so you can install new versions of default gems
add_default_gem_to_loadpath
end
real_require file # get slower as paths are added to LOAD_PATH
rescue LoadError
gem = find_gem_that_contains_file(file) # use a cache so lookup is O(1)
fully_qualified_path = gem.full_path file
real_require fully_qualified_path # send a fully qualified path, so LOAD_PATH isn't searched
end
~~~
Unfortunately, that means that every call to require in the system would raise an exception. I'd like to add a version of `require` that we can call that *doesn't* raise an exception. Then I could write the code like this:
~~~ruby
def require file
if file_is_from_a_default_gem?(file) # this is so you can install new versions of default gems
add_default_gem_to_loadpath
end
found = try_require file
if nil == found
gem = find_gem_that_contains_file(file) # use a cache so lookup is O(1)
fully_qualified_path = gem.full_path file
real_require fully_qualified_path # send a fully qualified path, so LOAD_PATH isn't searched
end
found
end
end
~~~
This would keep the load path small, and prevent exceptions from happening during the "normal" case.
I've attached a patch that implements `try_require`, but I'm not set on the name. Maybe doing `require(file, exception: false)` would work too.
---Files--------------------------------
try_require.patch (2.44 KB)
--
https://bugs.ruby-lang.org/