Coding For E2: A Primer

Hi, I'm kthejoker. You may know me from such E2 coding projects as the Wheel of Surprise, My Achievements, and that thing that's horrible and needs to be undone or the site will collapse any day now. You know the one.

I'm here today to help you learn the basics of what it takes to code for E2, and some of the basic tips and techniques to make your transition to E2 coder a smooth one. To help us out, we're going to be using the Epicenter nodelet as our chief document and reference guide. If I start talking about "the code", that's what I'm referring to.

The Basics: Perl

Before we get started diving into the code of Everything2, let's be clear: if you want to code in Everything2, you have to know some Perl. There are a lot of books and websites on Perl and its labyrinthine syntax and methods, but we're just going to cover the nitty gritty here. Basically, you need to know 4 things: variables, operators, functions, and loops.

Variables

The first thing you need to know about Perl variables in E2 is that we use strict mode, which means you must instantiate each variable in your code with the "my" syntax. This keeps everything in scope for the interpreter. We'll see how this used below.

There are three basic variable types in Perl: the scalar ($), the array (@), and the hash (%).

The scalar is just a single valued variable.

my $num = 1;

initializes a scalar variable called num and sets its value to 1. Notice we used the "my" to initialize the variable, and we ended the statement with a semi-colon - another Perl requirement.

The array is a variable that can hold multiple values in a numerically-indexed .. well, array. Generally, these values are scalar in nature, but you can also have an array of arrays, or an array of hashes.

my @array = (1, 2, 3);

initializes an array and sets its first three values to 1, 2, and 3, respectively.

The hash is the last variable type, and is generally much more important than arrays for E2 coding. A hash is a lot like an array, except its keys can be associative. So, for example,

creates a hash with two keys, title and author, and sets their values. You can then retrieve these individual values using the "$$" syntax - $$book{title} - or the "->" syntax - $book->{title}. When an E2 node is retrieved from the database, it is returned as a hash - this is the basis for doing most of the dirty work.

Obviously, there's a lot more to all of this, but for now, this'll get you started. When looking through code, identify scalars, arrays, and hashes, and try to determine their purpose. Sometimes their name makes them obvious ($$NODE{title}) - other times, not so much ($isHappyPanda).

Mathematical operators are pretty straightforward: +, -, *, and /. But there are also some shortcuts - for example, $num++; will increase the value of num by 1. $num += 100; will increase $num by 100.

The chief concatenation operator is the period (.). This is used to combine strings together. So if you have

my $word = 'Hello';$word = $word . ' World';

, then at the end, $word is equal to 'Hello World'. This also has a shortcut, .= , which gets a lot of use here on the site.

The comparison operators are a little trickier, because you have two different sets of them. The first set compares numbers and should be familiar: <, >, <=, >=, !=, and == (those last two are "not equal" and "equal to", respectively.) The second set compares strings and correlate with the numeric operators nicely: lt, gt, le, ge, neq, and eq.

Again, not comprehensive, but should help you understand what if ($$NODE{title} eq 'Butterfinger McFlurry') means.

Functions

Functions and subprocedures are great tools in Perl, but here at E2 we don't generally write our own functions - at least not directly (more on htmlcodes later.) The E2 Perl modules come with a bunch of handy subs, though, that get a lot of use, so you should be familiar with the syntax of a function call:

functionName(parameter1, parameter2, etc);

Not every function has parameters, but if they are required, you'd better have 'em. Also, many functions return a value that can be used in your code. A simple example is

my $fearlessLeader = getNodeById(220);

getNodeById does exactly what you think it does, and in this case returns Nate to the variable. Then we do something like

return $$fearlessLeader{experience};

which will then print the returned value (Nate's XP) to the display.

Loops

Loops and conditionals are a fact of life in programming, but luckily they're also pretty straightforward to understand. There are three main loops and conditionals in use at E2:

the if-else conditional. The syntax is

if (someBoolean) {doSomething;}else {doSomethingElse;}

The else statement is entirely optional - you can just say

if (canVote) {castVote;}

and be done with it. Also there is a shortcut for one line if statements - you can just do

$num++ if $notDone

and Perl will do as it's told. (You can also do $num++ unless $Done, but that's pretty rare.)

the for/foreach loop. The for loop allows us to run the same code a certain preset number of times. The foreach loop goes through each item in an array or hash and runs code. So, same result, but different ways to implement a loop. This is useful when, for example, printing every writeup under an e2node, or printing the top 20 Staff Picks.

the while loop. The while loop syntax is

while (someBoolean) {doSomething;}

and does what you would expect: while someBoolean is true, it keeps running the code. In this case, you can run into an infinite loop unless you include code that sets someBoolean to false somewhere within the loop.

I'm kind of glazing over these, because really reading an example is the best way to understand what's going on, which we'll cover in our next couple of sections.

Overview

So we've covered some of the basics of Perl. As we're going through code, you may find yourself asking what this or that bit of code is doing. Always try to break it down in terms of the variables, functions, loops, and operators being invoked. E2 isn't exactly a bastion of good documentation, so I often find myself backtracking from some error point until I get to the root variable or function that is really at issue. Being able to go from the big picture to the small detail is essential to understanding E2 code.

Next we'll talk about some of the basic syntax for E2-specific coding: the global variables, database calls, and htmlcode functions.