You are here

June 2009

Error message

Deprecated function: Function create_function() is deprecated in GeSHi->_optimize_regexp_list_tokens_to_string() (line 4716 of /home/web/ithiriel.com/www/web/sites/all/libraries/geshi/geshi.php).

GnuPG keys on USB

This is a reasonably simple process. Most of the process can be found in this Enigmail forum discussion.

  1. Move the GnuPG keys to a USB drive. (For the purpose of this discussion, I will assume that the USB drive is X: and the directory on the drive is .gnupg.)
  2. On the computer (not on the USB drive), change gpg.conf to include these directives:
    no-default-keyring
    keyring X:\.gnupg\pubring.gpg
    primary-keyring X:\.gnupg\pubring.gpg
    secret-keyring X:\.gnupg\secring.gpg
    trustdb-name X:\.gnupg\trustdb.gpg

    Under Mac OS X, assuming a volume name of USB drive, you would add:

    no-default-keyring
    keyring /Volumes/USB drive/.gnupg/pubring.gpg
    primary-keyring /Volumes/USB drive/.gnupg/pubring.gpg
    secret-keyring /Volumes/USB drive/.gnupg/secring.gpg
    trustdb-name /Volumes/USB drive/.gnupg/trustdb.gpg

    For Linux, it should be the same as for OS X but /Volumes/USB drive would be replaced by the mount point used for the drive.

  3. And that's it.

If you want to use an encrypted partition or filestore, e.g. through TrueCrypt, the above instructions are still valid. However, you would point it to wherever you have TrueCrypt mount the encrypted partition or filestore.

Project Euler as a Means of Learning

About four months ago, I wrote about Project Euler. Back then, I posted that I would do the problems in Ruby to try to hone my skills there. Since then, I've mostly done Ruby but I have also done some solutions in Haskell for speed reasons, namely prime number generation. (I should really revisit how I do that in Ruby...)

Project Euler is a good way to introduce some basic concepts. Each problem is best solved using a given set of the language. They are probably better exercises for those who like puzzles than the exercises normally taught in beginner books or in first semester programming courses. However, I see two problems with using Project Euler as a long-term means of learning a programming language.

First, Project Euler's focus is not on learning a given language or teaching about a given set of language features. Project Euler's focus is on the mathematical problems. More time in solutions, especially in later problems, is spent on figuring out the algorithm or method for solving the problem rather than on how to write that algorithm in a given programming langauge. Some language features or methodologies are never addressed because they never come up in the process of solving the problems.

Second, the scope of Project Euler problems is relatively small. The only focus within a given problem is answering that problem. Each solution amounts to a one-time script with components you might reuse later. As a result, Project Euler is insufficient for learning how to develop applications in a given language. (It may, however, have use in learning how to develop a library or module since some algorithms or components are used repeatedly.) There is not sufficient scope to investigate using it to develop an interactive application.

So I think that Project Euler works out well when first starting. However, once familiar with the basic concepts, supplementing or replacing Project Euler with another method of learning, e.g. building an application, is needed to ensure that there is further learning.

This is not to say that Project Euler should be completely abandoned at that point. It just ceases to be useful for learning about applying the programming language by itself. If you happen to enjoy the puzzles (I know I do), feel free to continue to do them.

Using Git For Websites

I've written before about using subversion and Piston for hosting this particular site.

The problem with using subversion for websites is that it is not available when working offline. (Assuming that your repository does not reside on your laptop.) While this is not normally an issue for sites based around a CMS, e.g WordPress or Drupal, there are times that having access to version control would be useful. Examples include working on a new Drupal theme or doing old-fashioned HTML web development.

The solution to this problem is to use a distributed version control system. In a distributed control system, a local repository is maintained on the development machine which is then periodically synchronized with the master repository. One such system is git. Git is used by the Linux kernel developers and many other projects besides. It also has the feature of being able to interact with subversion which is useful for me since I'm not ready to phase out my subversion repository.

At a glance, git appears to be superior for websites. Aside from the advantage of being distributed, it also stores its metadata in a subdirectory of the top-level directory called .git. Compare this against subversion which stores its metadata in a subdirectory called .svn within each directory and subdirectory of the repository. This means that if you have directories that are owned by the webserver (this happens on websites sometimes), you have to get them chown'd before you can add them to a subversion repository. With git, this isn't an issue. (Git will not preserve the file ownership but this isn't usually a significant issue.)

There are a few differences between subversion and git. First, git does not use a central repository like subversion. A common structure in subversion would be to have a central repository and then each project would be a subdirectory. In git, each project has its own repository. While you can check out specific directories from subversion, you can only check out the entire repository for git.

While subversion allows checking in empty directories, git does not. This can be an issue for some applications. The Git FAQ suggests, as a workaround, adding a fiele called .gitignore to each otherwise empty directory. Git will then check in the .gitignore file.

Git does not appear to support anything like svn:externals. However, this does not appear to be a significant issue. Version 2 of Piston supports git (as well as subversion) so it can be used to fulfill the same purpose. (Correction: As Jakub Narębski points out in the comments, git's submodule mechanism is a lot like svn:externals.)

Using git is mostly the same as with subversion. If you are familiar with subversion, you should pick up on the commands relatively quickly. (And if you're completely new to version control, I suggest getting Pragmatic Version Control Usng Git.) The one major catch is: Always remember to push commits to the central repository with svn push origin master. If you do not do this, the local commits will never reach the repository. This is an issue if you expect to redeploy the site from that repository in the future.

Finally, when using Git and Piston, you will need to add these directives to block access to the metadata:

RedirectMatch 404 /\\.git(/|$)
RedirectMatch 404 /\\.piston.yml

If still checking out from a CVS repository, e.g. from Drupal, you will still need to include this as well:

RedirectMatch 404 /CVS(/|$)

Using include_path in PHP

Common convention states that include files for a PHP web application should be kept in a given place. This allows the developer to easily find them.

This becomes a headache though when a site is deep and has many subdirectories. You then start seeing code like:

require_once( '../../../../../../includes/config.php' );

This creates a headache for developers since they have to remember where a page is in respect to the includes directory. If the page is moved to a different subdirectory, the path in the require_once (of, if you prefer, include, require, or require_once) statement needs to be changed.

A simple workaround for this is to add the root directory of the site (or whichever directory is just above the includes directory) to PHP's include path.

Let's assume a directory structure like:

/var/www/sites/example.com/
  `- www/
      |- logs/
      `- web/
         |- includes/
         |   `- config.php
         |- test/
         |   |- test/
         |   |   `- test /
         |   |       `- test2.php
         |   `- test.php
         `- index.php

In order to include includes/config.php without modifying the include path, each page would use a different path:

  • index.php:
    require_once( 'includes/config.php' );
  • test/test.php:
    require_once( '../includes/config.php' );
  • test/test/test/test2.php:
    require_once( '../../../includes/config.php' );

Now, if /var/www/sites/example.com/www/web is added to PHP's include path, all three scripts can load config.php with the statement:

require_once( 'includes/config.php' );

This clearly reduces the hassle of maintaining and referencing the single directory for includes.

To add the /var/www/sites/example.com/www/web directory to the include path, it must be appended to the include_path configuration setting. To do this for PHP running under Apache using mod_php, the following line can be added in a .htaccess file or directly to the site's VirtualHost paragraph:

php_value include_path '.:/usr/local/lib/php:/var/www/sites/example.com/www/web'

(This assumes that PEAR modules are stored under /usr/local/lib/php.)

If this is the only site on the server, the include_path setting can be edited in php.ini. If using a CGI-based PHP, you may be able to create a local php.ini for this same end. Consult the PHP documentation on runtime configuration for more information.