Project

General

Profile

Feature #16246

require with an optional block that is evaluated when requiring fails

Added by sawa (Tsuyoshi Sawada) about 1 month ago. Updated about 1 month ago.

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

Description

I have some code like this:

begin
  require "foo"
rescue LoadError
  puts "You need to install foo in order to have the function A work."
  ...
end

I request to allow require to take a block which is executed when requiring fails. When require takes a block, a LoadError would not be raised. The code above would then be written like:

require "foo" do
  puts "You need to install foo in order to have the function A work."
  ...
end

If there is no need to particularly do anything, then it can be like

require("foo"){}

which will cover the use case in https://bugs.ruby-lang.org/issues/14565.

History

Updated by shevegen (Robert A. Heiler) about 1 month ago

:)

I kind of like the idea (ok ok a bit of self-patting by me, so ...).

I think my primary objective was more my laziness, though.

For example, nobu had shown examples which are a common idiom like:

require 'foo' rescue LoadError

Something along those lines. This has the advantage of a single line,
but on the other hand I personally prefer if the code logic is more
aligned on the left hand side. So for example:

begin
  require 'foo'
rescue LoadError; end # And perhaps extend this lateron when providing
                      # feedback to the user, or tell the user to do a
                      # "gem install foo".

But I think in my case, it is more about being lazy.

One small issue is that I think idioms that should be used, should ideally
be used by lots of different ruby people. For example, refinements, and
the syntax suggestions in the last ~2 years or so.

Anyway, sorry for the off-topic comment here. I did want to make a larger
proposal for getting rid of require/load statements, e. g. reaching a state
where we do not have to add require calls to every individual .rb file, but
I have found it to be quite difficult to propose a mechanism that would be
useful, and used by many people (just for projects that are arranged via
a gem already). I also think the old ways for require() and load() will
have to remain as they are, due to various reasons, not only backwards
compatibility, but I think that matz, the core team and possibly many
users wish for require/load to remain simple (sort of). And I am not even
sure how to propose a proper system that would allow us to avoid
require/load ... or a hybrid system, where you could specify different
"entry" points. A bit like public/private, but on a require-like level.

Partial ideas here were to be able to avoid circular warnings (because
ruby would know how the files relate to one another), and also to no
longer depend on hardcoded entries (e. g. require 'foo/bar/bla.rb'
versus a system where you could do something else ... like
require_project 'NAME_OF_THE_GEM|entry_point' ... but it is really really
difficult for me to come up with an elegant, simple system, that would
be flexible, simple to understand, simple to use ... perhaps someone
else can come up with some advanced code-loading system for ruby 4.0
or so ... without hardcoded paths, we could always specify to the same
"API", even on the filesystem level ... but I really find it difficult
to come up with something elegant here. I am not creative enough.)

Sorry for the off-topic comments here from me.

Also available in: Atom PDF