This is in the category of "things that work, but make me nervous."
I use a very complicated, custom document class with LuaLaTeX. But my question can easily be illustrated with this generic MWE:
\documentclass{article}
\RequirePackage{xifthen}
\RequirePackage{letltxmacro}
\LetLtxMacro\myusepackage\usepackage\relax
\LetLtxMacro\myRequirePackage\RequirePackage\relax
\renewcommand\usepackage[2][]{%
\ifthenelse{\equal{#2}{hyperref}}{}{\myusepackage[#1]{#2}}%
}
\renewcommand\RequirePackage[2][]{%
\ifthenelse{\equal{#2}{hyperref}}{}{\myRequirePackage[#1]{#2}}%
}
%
\usepackage{xstring} % should work
\usepackage{hyperref} % should do nothing
%
\begin{document}
OK
\end{document}
If the user attempts to load hyperref, it will silently be ignored. I realize that there are alternative such as \PassOptionsToPackage, but that is not the effect I seek.
I routinely patch commands from various LaTeX packages, but those are high-level commands in optional packages, rather than something as fundamental as \usepackage or \RequirePackage. So my question is: Does the above MWE code have any hidden traps?
I only chose hyperref for purposes of the MWE, so there's no need to ask why I would want to block it in a real document.
EDIT: For those who wonder why I would do this: My custom document class requires certain things to be loaded in precise order, due to \immediate\write commands. If the user loads a package prematurely, currently I detect that by throwing an error via \@ifpackageloaded in the class code, just before my own code loads the package \AtEndPreamble. But it seems to me that it would be more user-friendly to simply ignore the premature loading.
EDIT2: Based on comments and answers, I believe that I should retain my current method, rather than doing what the question asks. "Bad user interface" (per DC) is an important point.
Without getting into the over-200K bytes of my custom document class, I can illustrate what I have been doing. This has been in good working order for many months. General concept of "myscustomclass.cls" is this:
a) When mycustomclass loads, it also loads and pre-configures numerous packages. It also provides its own commands.
b) It contains \AtEndPreamble that will load and configure additional packages. These cannot be loaded until after the user's preamble, since it needs to look at the user's preamble and decide what to do.
c) At least one of the later-loaded packages has \immediate\write, which cannot occur earlier than a certain time. That is why it is deferred until \AtEndPreamble.
Currently (good working code) I do this kind of thing:
\AtEndPreamble{
% lots of code here
@ifpackageloaded{hyperref}{ % Should not have been loaded by user! Too early!
\ClassError{mycustomclass}%
{Cannot load hyperref in preamble}{See myscustomclass docs section XX.XXX}
}{
\usepackage[various options]{hyperref}
}
% lots of code here
}
\expandafter\def\csname ver@hyperref.sty\endcsname{3000/12/31}seems a better choice for ignoring the loading of a package. See https://tex.stackexchange.com/a/85700/4427 for an example of what can go wrong. – egreg Jan 28 '18 at 00:59\hrefthey will just get an undefined command error with no hint of why. Better if your class went\AtBeginDocument{\@ifpackageloaded{hyperref}{\ClassError{myclass}{I told you not to load hyperref}{}}{}}so the user gets a more relevant message. – David Carlisle Jan 28 '18 at 01:05\hyperrefin the class code. It is a matter of timing. See my edit to the question. – Jan 28 '18 at 01:26hyperrefwith options? What if they follow the loading with\hypersetup? What if they next loadcleveref? What if they loadbookmark? – cfr Jan 28 '18 at 01:31\AtEndPreamble. So the question is not "what if," the question is "does my method work." As David Carlisle shows in an answer, there are indeed issues that I had not addressed. – Jan 28 '18 at 01:39hyperrefis loaded\AtEndPreambleat a specific time. Cannot be loaded earlier, such as during Preamble by the user. That's not the only package involved, I just picked it for illustration. – Jan 28 '18 at 01:44\hypersetup{...}commands you need at that point. – David Carlisle Jan 28 '18 at 01:52hyperref, but then they'll get an error when the next line is\hypersetupor more mysterious failures withcleveref. Or they'll get an error if the next line loadsbookmark. The same goes for lots of other packages. People often load them and then do config in the preamble. The fact that the config commands will be loaded at the end of the preamble doesn't help. Any package which loads a package you drop will also cause trouble, as it will try to execute commands not yet defined. This isn't just abouthyperref. – cfr Jan 28 '18 at 02:10hyperrefor the other forbidden packages, because they won't work as expected. The purpose of my code is to catch those who don't read the docs. Of course, I cannot deal with every single LaTeX package, because there are so many of them. But I can address the ones most likely to be used, out of force of habit. – Jan 28 '18 at 02:16