Tag: technique

DRYing up tasks makes life easier

When writing scripts that perform the same task over and over again with different parameters, it is tempting to just cut and paste. Here’s an example of a bash script:


#!/usr/bin/env bash
grunt make_magic --dir=/foo
grunt make_magic --dir=/bar
grunt make_magic --dir=/lorem
grunt make_magic --dir=/ipsum
grunt make_magic --dir=/magnum
...

Imagine that goes on for hundreds of directories!

This isn’t very DRY. If we wanted to add an extra parameter to the grunt command, we’d have a lot of editing to do.

If we needed to do another command on those very same directories, we would have to enter the directory names again. As you can see, it would be very easy to forget to add all of them.

DRY

DRY stands for “Don’t Repeat Yourself”. If some code or commands are duplicated elsewhere, that’s a sign that there are inefficiencies in the code.

The idea behind this is to pull out common code into functions/methods. When a change to that code is required, it only needs to be made once. If a bug is identified in the code, once it is fixed, it is fixed “everywhere”.

DRYing

Let’s take the example above and dry it up. We have to run the same command with different parameters (directories), so we will create an array of directories:

DIRS=( foo bar lorem ipsum magnum )

Now we write a “for…each” loop to do something for each element in the array:


for thedir in "${DIRS[@]}"; do
grunt make_magic --dir=/$thedir
done

This works on each element of the DIRS array and assigns it to thedir variable, which is now available inside the block.

Using this technique, it is very easy to add additional commands and/or directories.

Decoupling presentation from content

Box model in CSS
Box model in CSS (credit: Wikipedia)

I recently ran across the anti-pattern of what I see as a common problem amongst designers and developers: coupled presentation and content. I’ve found that decoupling the presentation from the content makes things much easier to write, maintain and expand.

Here’s a simple example:

HTML

<section>
    <div class="margin-top-10">Lorem Ipsum</div>
</section>

CSS

.margin-top-10 { margin-top: 10px };
.margin-top-20 { margin-top: 20px };
(etc)

Take a look at what is going on here: we’re adding a 10px margin to the top of the div. DON’T DO THIS. You want your class names to be contextual, not descriptive of the style.


Rule of thumb

To change the layout, you should only have to edit the CSS, not the HTML.

Here’s where our anti-pattern falls down and will cause grief.

  1. You decide to adjust the positioning of the section. You can:
    • Edit the CSS, changing the class’s margin value and breaking every other element that uses that class.
    • Edit the HTML create a new class, then edit its CSS class definition. If you have to experiment with different margin values, you’ll need a LOT of classes. “Will 14px work or 15px? What about .25em? Argh!”
  2. You can’t have too many attributes in each class, because they will have unintended consequences for the other elements that are using them. Add a red border to one class because you need a border for a specific element, now you have red borders on ALL the elements that share that class. So, you’ll have to have many single- (or few-) attribute values, and include all of the necessary ones on the required HTML elements.
  3. The violent psychopath maintenance programmer (who knows where you live) will kill you in your sleep. You have made her job insanely hard by turning this:
<div class="margin5 blueborder mediumwidth floatingleft" ...

into this

<div style="margin:5px;border:3px blue outset;float:left;width:75%" ...

for no good reason.

The Cure

Think about the element in terms of content or a functional space. What is it and what does it do? In our example above, let’s assume it is the lede section of an article. Then we would do:

HTML

<section>
    <div class="lede">Lorem Ipsum</div>
</section>

CSS

.lede { 
  margin-top: 10px;
  border-bottom: 2px #9fe2f9 outset;
  float: right;
  position: relative;
  width: ...
};

By decoupling the content (div) from the presentation (style-dependent class), we are free  to adjust the style of that element by making whatever changes to the CSS and leaving the HTML alone.

“But,” you shriek, “I have common elements for everything! Rounded corners! Gradients! (except IE…) Et cetera!”

 

For this, we will turn to our trusty companions Less and/or Sass in a future post.

SASS: Style w/ Attitude
SASS: Style w/ Attitude
Enhanced by Zemanta

Regular Expressions Roundup

Writing some Regular Expressions?

Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.
—Jamie Zawinski

Well, not really. There are some cases where using a Regular Expression—RegEx— instead of a heap of convoluted if statements just makes sense from both a lazy and practical standpoint.

When you’re knee-deep in writing your RegEx, you’ll need to test. My favorite RegEx ‘workbench’ is Oliver Steele’s “reWork.”

screenshot of reWork

To get a jumpstart on writing complex RegEx,  check out the Regular Expression Library, which contains a plethora of user-submitted RegEx recipes. Some of them are quite good (check each recipe’s rating).

screenshot of example page

Enhanced by Zemanta

Find Something You Like and Dissect It

Image representing Wikipedia as depicted in Cr...
Image via CrunchBase

I’m always on the lookout for a new technique or Better Mousetrap. I admit I don’t know all that much, so I’m happy to learn.

I was playing around with Wikify @ appointment.net (a nifty tool that goes through a block of text and ‘wikifies’ it–that is, links all the words it can find to relavant Wikipedia articles) when I noticed the behavior seemed rather…odd. I could see it go through the word list as it created links, and every time it linked up a word, every duplicate word was linked.

Let’s take some example text (from the now-defunct Dilbert Mission Statement Generator) and run it through the site:

“We have committed to synergistically fashion high-quality products so that we may collaboratively provide access to inexpensive leadership skills in order to solve business problems

Our mission is to continually leverage existing seven-habits-conforming catalysts for change as well as to competently leverage other’s error-free materials.

We globally leverage other’s professional meta-services as well as to conveniently integrate competitive solutions in order to solve business problems.

“It is our job to continually foster world-class infrastructures as well as to quickly create principle-centered sources to meet our customers needs

“Our challenge is to assertively network economically sound methods of empowerment so that we may continually negotiate performance based infrastructures

For example, the additional instances of “leverage,” “problems,” and “business” were quickly linked, once the first one was completed. Poking around their code, I noticed all the action takes place in wikify.js. There are a few gems in there. For example, the function call to reduce an array to only unique values:

function array_unique( array ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      input by: duncan
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Nate
    // +      input by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Michael Grier
  // %          note 1: the second argument, sort_flags is not implemented
    // *     example 1: array_unique(['Kevin','Kevin','van','Zonneveld','Kevin']);
    // *     returns 1: ['Kevin','van','Zonneveld']
    // *     example 2: array_unique({'a': 'green', 0: 'red', 'b': 'green', 1: 'blue', 2: 'red'});
    // *     returns 2: {'a': 'green', 0: 'red', 1: 'blue'}

    var key = '', tmp_arr1 = {}, tmp_arr2 = [];
    var val = '';
    tmp_arr1 = array;

    var __array_search = function (needle, haystack) {
        var fkey = '';
        for (fkey in haystack) {
            if ((haystack[fkey] + '') === (needle + '')) {
                return fkey;
            }
        }
        return false;
    };

    for (key in tmp_arr1) {
        val = tmp_arr1[key];
        if (false === __array_search(val, tmp_arr2)) {
            tmp_arr2[key] = val;
        }
        delete tmp_arr1[key];
    }
    return tmp_arr2;
}

Aha! See how that works?

Enhanced by Zemanta