From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Tim X Newsgroups: gmane.emacs.help Subject: Re: test for presence of library Date: Sat, 20 Feb 2010 12:09:51 +1100 Organization: Rapt Technologies Message-ID: <878wao67c0.fsf@lion.rapttech.com.au> References: <87mxz6116b.fsf@galatea.lan.informatimago.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1266630046 9205 80.91.229.12 (20 Feb 2010 01:40:46 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 20 Feb 2010 01:40:46 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sat Feb 20 02:40:43 2010 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1NieKm-0003ms-VU for geh-help-gnu-emacs@m.gmane.org; Sat, 20 Feb 2010 02:40:41 +0100 Original-Received: from localhost ([127.0.0.1]:35400 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NieKm-0004k4-8n for geh-help-gnu-emacs@m.gmane.org; Fri, 19 Feb 2010 20:40:40 -0500 Original-Path: news.stanford.edu!usenet.stanford.edu!news.kjsl.com!news-xfer.nntp.sonic.net!news.astraweb.com!border2.newsrouter.astraweb.com!not-for-mail Original-Newsgroups: gnu.emacs.help User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.92 (gnu/linux) Cancel-Lock: sha1:BAEr1J4Bo7mo0J33erVozEUaPwY= Original-Lines: 167 Original-NNTP-Posting-Host: 98d89b8d.news.astraweb.com Original-X-Trace: DXC=135LlL`e9K1SG6fD[7G; H=L?0kYOcDh@:a30YlQ[TC>:MENCm8nL]18^J:1TlA[]=2@R`U9dCaf`8 Original-Xref: news.stanford.edu gnu.emacs.help:176899 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:71967 Archived-At: Harry Putnam writes: > pjb@informatimago.com (Pascal J. Bourguignon) writes: > > [...] > > Harry wrote: >>> The lisp equivalent of: >>> >>> if some-lib >>> then >>> (require some-lib) >>> fi >> >> >> require does the test itself! >> >> C-h f require RET >> >> >> Now, assume that we wrote: >> >> (when (library-exists-p 'some-lib) >> (require 'some-lib)) >> >> and that just after your emacs executed (library-exists-p 'some-lib) >> and returned true, some other process would delete that some-lib.el >> file. What would happen to your (require 'some-lib)? >> >> >> That is, basically, your above shell script with if [ -f /my/file ] is >> just WRONG! If you see such tests in scripts, you are allowed to think >> poorly of their authors. > > Don't hold back, in this case you are allowed and really forced to > think poorly of the author who admits to having literally hundreds of > such tests scattered thru a 10yr accumulation of various scripts in > various scripting languages. > > I'm a known dimwit... its even ok to use the `R' word... I doubt (Sarah > Palin reads this group) > > It's ok, I've learned to live with it. > > Now lets assume further that we instead say simply: > > (require 'some-lib) > > After patting myself on the back for such a wise solution to getting a > needed library loaded, I move to a different and new machine where I've > carted my every ready .emacs file with me. > > I start emacs with `emacs /some/path/file'.... but whoops, since > `some-lib' is not in the path in this environment... my emacs blows up > a bit. It throws up a confusing buffer full of various leads to > information, but none of it appears to bear directly on the job at > hand. .. Not even any indication of what the problem is. > > I finally noticed at the bottom, a place to dismiss this interruption > and get back to work. > > I'd like to avoid that even though its not really an earth shaking > problem. > > My first thought, being a dunce and all, was to test for the presence > of the library before requiring it, thereby smoothing out the work > flow and interruptions. I wasn't sure how that would be done, hence > the question here. > > But looking at the suggested documentation I'm left non the wiser: > > (require FEATURE &optional FILENAME NOERROR) > > That isn't going to get it for me.. I've tried a few arrangements but > being an idiot and all, I have no idea how something optional is > introduced into the require. > > What do you recommend to a simpleton regarding how to avoid the > interruption? Just make sure all is perfect before starting emacs? > > Or maybe spend a day or two figuring out how to apply the codified > documentation.... again... thats' a hard pull for the intellectually > crippled. > Maybe consider the issue form a slightly different perspective. You can have two scenarios when it comes to loading a library 1. If the library is not found, throw an error and let the user deal with it. The advantage of this approach is that you can be confident that if no error is thrown, you the library has been loaded and the features it provides are available. The disadvantage is that if an error is thrown, the user has to take some action, which may be as simple as telling emacs to ignore the error and continue. Unfortunately, further errors could arise when something in your .emacs tries to use the feature that would have been available if the library had loaded successfully. 2. Tell emacs to try and load the library, but don't throw any error if it fails. This has the advantage that the user does not have to take any action when emacs can't load the library. However, unless other precautions are taken, you may get errors further along when emacs tries to use a feature associated with that library. >From what you have written, I'm assuming you currently have the first situation, but would like something more like the second situation. both approaches can be handled using require and the predicate featurep. The require directive takes an optional second argument 'noerror'. If you have (require 'mylib nil t) emacs will not throw an error if it fails to find the library 'mylib. This will give you the first part of a solution outlined in scenario 2. However, you may still get an error thrown if later lines in your .emacs try to use a feature that is associated with that library which is not available. What we need to do is only try to use the feature if the library was successfully loaded. If you look at most libraries, you will find, usually at the end, a line such as (provide 'mylib) This tells emacs that the feature 'mylib has been loaded. this has two benefits,. 1. If you have multiple 'require' lines for the same library, it will only be loaded once as require checks to see if the feature has already been 'provided'. 2. You can use the featurep predicate to test and see if a library has been loaded. So, the second part of the solution is to ensure that any config or commands that use features provided by a library always test to see if that feature has been loaded before trying to use it. Yo would end up with something like (require 'mylib nil t) ... ... ... (when (featurep 'mylib) (do-something-using-mylib) (do-another-thing-using-mylib)) Whith these two lines, you can use the same .emacs file on different machines wherre one has the library and one does not and you won't get bothered with errors at startup. Of course, you could still get errors when using emacs if you try to use a feature associated with the library that isn't available, but at least you won't get emacs stalling when it tries to load. HTH Tim -- tcross (at) rapttech dot com dot au