the tourist

May 10

Updating Your Bash

OSX’s bash is terribly out of date, as was pointed out to me today by 8th Light Craftsman Eric Meyer.

My machine was using bash 3.2.48 and the most recent version of bash is 4.2. In this post I’ll walk you through the steps needed to update your bash.

But first, an unexpected and exciting (and brief) look into tar files! TAR stands for Tape Archive. Why? Well, originally it was designed for tape backups. What the heck is a tape? There’s a device called a tape drive that reads and writes data on a magnetic tape. Check it out!

Wow! That thing looks like it’s a hundred years old! In contrast to a disk drive, which can move to any position on the disk in milliseconds to retrieve data, a tape drive must physically wind tape between reels to read data. But what you lose in speed you make up in cost. Tape drives are much less expensive.

So we go grab this tar file of the newest version of bash. (Note: a tar does not compress the files).

First, click here to grab the tar of bash 4.2.

Enter the Downloads folder.

cd ~/Downloads

Let’s learn about some tar commands now that we have a tar file to deal with.

  • z uncompress before extracting
  • x is to extract files ending in .tar.gz or .tgz
  • v is to be verbose as it’s extracting
  • f is filename to follow

    tar zxvf bash-4.2.tar.gz
    

Wait! What is this .tar.gz extension? Remember when I told you tar files aren’t compressed? .tar.gz files are compressed tar files, which is why we had to supply the z flag to uncompress before extracting it.

Look at Wikipedia’s pretty picture of it all!

Alright, now hop into your brand new, freshly created bash-4.2 folder.

cd bash-4.2

Now we’ll just run three commands in a row all on one line. These three steps are very standard for obtaining software directly from the source code.

We’ll execute the configure script, the make command uses the makefile to determine what needs to be recompiled (and recompiles them). It does not recompile the entire program, only what’s needed.

make install performs the install, also specified in the makefile (which is essentially a file of instructions). It’s common for this command to install executables after the compilation process is complete.

The binary is installed at /usr/local/bin/bash.

./configure && make && sudo make install

Change your login shell to the bash shell you just downloaded.

chsh -s /usr/local/bin/bash your_user_name

chsh only allows you to switch to the shells listed in /etc/shells, so we need to register the new binary as a valid shell. The bash manual tells us that if the -c option is present commands are read from string.

sudo bash -c "echo /usr/local/bin/bash >> /private/etc/shells"

Enter the bin folder.

cd /bin

Re-name bash folder to bash-old, thereby creating a “backup” copy.

sudo mv bash bash-old

Create a symlink to point /bin/bash to /usr/local/bin/bash.

sudo ln -s /usr/local/bin/bash bash

Now if you run this command you can check the version of bash you’re using.

bash --version

And finally, read about the new stuff in bash 4.X.

Some Helpful Stuff

The Ultimate Tar Command Tutorial with 10 Practical Examples

BashGuide

Learning the shell


May 9

Running a PHP App Locally Using Apache

Today Paul asked Nhu (a fellow apprentice) and I to get a PHP app running locally so he could begin the process of determining the best way to re-write it as a Rails app.

We weren’t very familiar with PHP or Apache, the web server we decided to use, so it took a while to figure everything out. We have the app running locally now and I wanted to explain how we got there.

Apache and PHP come with OSX, but they aren’t enabled by default. The Apache binary running under Unix is called HTTPd (for HTTP daemon). The core of Apache is fairly basic and the server integrates easily with PHP and many databases.

cd /etc/apache2

This is where your machine’s Apache server is located. You’ll see a number of files and folders here, including one called httpd.conf. Apache is going to look at these *.conf files (configuration files) to determine a number of things, such as what port to listen on.

This file needs to be edited, but it’s read-only so you’ll have to change permissions on the file.

sudo chmod 755 httpd.conf

755 is the same as u=rwx,go=rx, meaning that you’re giving the user read, write, and execute privileges, and the group and other privileges to read and execute only (but not to write). Read permission is assigned a value of 4, write is assigned 2, and execute 1. So giving read, write, and execute privileges is 4+2+1 (7), hence the reason for 755.

Next, we needed to uncomment a line in this config file that contains this command:

# LoadModule php5_module libexec/apache2/libphp5.so

Uncommenting this line is effectively enabling PHP.

At this stage we are ready to start the Apache server. We can start and stop (and restart) with these commands:

sudo apachectl start
sudo apachectl stop
sudo apachectl restart

But what files are we serving? If we visit localhost what will we see? Well, if we go back to the config file we edited earlier and take a look around line 165 we’ll see a commented out chunk of text explaining something called DocumentRoot.

# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.

DocumentRoot "/Library/WebServer/Documents"

So by default it will take files from this location to serve. There is an index file there that’s served when we hit the root route. It gives us the reassuring message “It works!”.

We wanted to serve our PHP app so we copied it to this directory and we were all set.

Some Helpful Stuff

An Introduction to Apache

Introduction to the Apache Web Server

Running PHP on the Mac OS X Leopard Apache Web Server

PHP: Built-in web server

Apache HTTP Server


May 8

Closures

A closure is a function plus a pointer to that function’s scope. Peter Landin, a British computer scientist, defined the term in 1964.

I found what I consider to be a simple, understandable example that I want to share.

outer = function() {
    var a = 1;
    var inner = function() {
        alert(a);
    }
return inner;
}

fnc = outer();
fnc();

Essentially, a closure is a function that has access to variables or values outside its scope. In the example, we define a variable a, then define a function inner within another function outer. inner has access to variable a. Because outer returns function inner, function fnc has access to a. a is local to the scope where inner was defined, so the pointer to a exists.

At run-time, when outer is invoked (outer()), a closure is formed, which consists of inner’s code and references to outer’s variables (a in this case) required by the closure.

It’s common to read and write functions that only make use of the variables defined within their own scope. Closures, as you saw above, provide access to variables outside of a function’s scope. The closure is not only a function, but also a pointer (as mentioned in the opening sentence). That pointer is a referencing environment, something Wikipedia defines as:

a table storing a reference to each of the non-local variables (also called free variables) of that function

A function pointer is a way to access executable code in memory. Instead of pointing to data, it points to a function that can be invoked after being dereferenced (the process is referred to as an indirect function call). It’s different than a closure because it does not allow a function to access non-local variables.

Closures are most commonly seen in functional languages (those in which functions are first-class citizens), but are possible in OO languages as well.

So why use closures? Well they enable you as a programmer to write cleaner, more readable code, for one thing. They are a very convenient, idiomatic way to give a function access to local state without creating a new class/object, etc. A function’s closure is essentially the same as a class’ member variables. With closures you gain the power to access a block of code and the context in which that code was defined. You therefore can make use of that context (the variables defined within it, for example) later on if needed.

I’ll leave you with this additional explanation:

A closure is a function that has one or more variables bound to it. The two are basically identical, at an implementation level at least. The real difference is in where they come from.
In object-oriented programming, you declare an object class by defining its member variables and its methods (member functions) up-front, and then you create instances of that class. Each instance comes with a copy of the member data, initialized by the constructor. You then have a variable of an object type, and pass it around as a piece of data, because the focus is on its nature as data.
In a closure, on the other hand, the object is not defined up-front like an object class, or instantiated through a constructor call in your code. Instead, you write the closure as a function inside of another function. The closure can refer to any of the outer function’s local variables, and the compiler detects that and moves these variables from the outer function’s stack space to the closure’s hidden object declaration. You then have a variable of a closure type, and even though it’s basically an object under the hood, you pass it around as a function reference, because the focus is on its nature as a function.

Some Helpful Stuff

Stack Overflow: What is a ‘Closure’?

Cornell University Department of Computer Science: Capsules and Closures

Stack Exchange: What is a closure?

What are closures?


Page 1 of 27