Getting closure in JavaScript

wooden heart

If you’re coming from an imperative programming background, closures in JavaScript can be pretty hard to grok. Here is yet another attempt to explain them. It assumes you are familiar with how lexically scoped, imperative languages like C, C++, and Java work.

In JavaScript every function call creates its own lexically scoped context. Normally that context is destroyed at the end of the function call. However, you can keep that context alive by creating a closure.

The function inner below creates a closure. Because there exists a reference to the inner function from the calling code after the function returns, neither the inner function nor its context are destroyed. In other words, inner‘s context (including vars local to countFrom) lives on after the call to countFrom returns.

function countFrom(num) {
    var counter = num;
    var inner = function() {
        // return the value of counter before increment.
        return counter++;
    }
    // return a reference to the inner function.
    return inner;
}

var countFromOne = countFrom(1);
/* countFromOne now refers to inner()
   with a unique, persistent context. */

window.alert( countFromOne() );  // alerts 1
window.alert( countFromOne() );  // alerts 2
window.alert( countFromOne() );  // alerts 3

var countFrom42 = countFrom(42);
/* countFrom42 refers to inner()
   with different, persistent context. */

window.alert( countFrom42() );  // alerts 42
window.alert( countFrom42() );  // alerts 43
window.alert( countFrom42() );  // alerts 44

/* The context associated with the inner from
   countFromOne is not affected by the above. */
window.alert( countFromOne() ); // alerts 4

Once you get the basic concept, you should be able to follow other examples that show how they can be useful.

P.S. Neckbeards think not naming things is cool, so here’s an anonymousy version of the function above.

var countFrom = function(num) {
    var counter = num;
    return function() {
        return counter++;
    };
};

PDF output from KiCad in Linux from SVG

kicad-appicon-128

The ps2pdf-d script I developed earlier worked fine for getting PDF from KiCad‘s Eeschema using Postscript as an intermediate format, but it falls short with Pcbnew because there is no way in Pcbnew to make a Postscript file that merges layers. Using File > Plot, you can pretty easily get Postscript files of individual layers, but you can’t get a merge of, say, the top copper, top silkscreen, and drawing layers.

But you can do this with File > Print SVG. You’ll need to play around with the dialog to get the SVG you want, but it’s pretty simple. Thus, svg2pdf-d was born:

#!/bin/bash

# DESTRUCTIVELY convert all svg files in working directory to pdf.
# Source file extension is case sensitive!

# Requires inkscape.
# Mithat Konar 2013 <http://mithatkonar.com>

OPTIONS=""

FILES=$(ls -1 *.svg)

# There are two alternatives below for doing the conversion.

#~ ## BEGIN ALT_1:
#~ ##     This approach isn't optimal because it restarts inkscape per
#~ ##     file. However the simplicity lends itself to porting (e.g., to
#~ ##     windows BAT.
#~ for file in $FILES
#~ do
    #~ base=$(basename $file .svg)
    #~ inkscape --without-gui ${OPTIONS} ${file} --export-pdf=${base}.pdf
#~ done
#~ ## END ALT_1

## BEGIN ALT_2:
##     This approach seems to be better because it starts one inkscape
##     instance for all files, but it also involves a temp file.
# Make a temp file to store batch commands.
CMDFILE=$(mktemp) || { echo "Failed to create temp file"; exit 1; }

# build up the list of commands
for file in $FILES
do
    base=$(basename $file .svg)
    echo "${file} --export-pdf=${base}.pdf" >> $CMDFILE
done

# Process commands in a batch.
DISPLAY= inkscape ${OPTIONS} --shell < $CMDFILE rm -f $CMDFILE echo ## END ALT_2 # Delete old files. # Since inkscape exits with 0 even with errors, we need to explicitly check # for conversion before deleting originals. rv=0 for file in $FILES do     base=$(basename $file .svg)     if [[ -f ${base}.pdf ]]; then         rm $file     else         echo "$file not converted." 1>&2
        rv=1
    fi
done
exit $rv

svg2pdf-d requires Inkscape, which is not really that light. But it’s arguably something that should be in your FOSS toolkit anyway.

The Inkscape conversion used in svg2pdf-d seems to work fine with the SVG files generated by Eeschema as well. I’m seeing only minor differences between the SVG→PDF versus PS→PDF conversions, and the SVG→PDF files appear to have truer color. So the SVG approach may be the better one in general.

I’ll add I have added this to the wiki after a bit more testing making significant revisions.

Git again

git-logo

I’ve finally gotten around to using Git instead of Mercurial on a project. So far it has been uneventful. I still prefer Mercurial because it treats all OSes as first class citizens and because I think the CLI is cleaner. My workflow doesn’t require a lot of branching, but Git fans seem to think it really shines there. My main motivation for going Git on this project is to get some experience with what will likely become the defacto standard DVCS.

I am mostly using git-cola git gui as a GUI frontend. Ironically, git-cola—like Mercurial but unlike Git itself—is Python powered.

The best resource I’ve found so far for working with Git if you already know DVCS fundamentals is Spherical’s “Git for the lazy.” Entp’s “Version Control for Designers” is pretty good too.

Google Talk alternatives

google-talk-developers

Google Talk has been my preferred instant messaging service for years because it federates with other XMPP services. In other words, if someone wants to IM with you, she doesn’t need to sign up with Google; she can sign up with anyone who offers XMPP services or she can install an (open source) XMPP server on her own machine and connect with you with that.

All that is changing. A while back, Google limited XMPP federation, then reinstated it claiming it was done as an anti-spam measure. More recently, the huge Google Hangouts rollout finds XMPP federation at best being shoved to a back seat and at worst being entirely deprecated. Given that http://talk.google.com now redirects to http://www.google.com/hangouts/ it’s pretty clear that Google Talk is a deprecated service–so it’s hopeless to hang onto whatever federation Google Talk itself might provide. Federation lost.

Therefore, I will probably be shifting my default online presence from Google Talk to an account provided by someone offering unfettered XMPP service. Candidates include jabber.org (who I hope have solved their DDoS problems) and DuckDuckGo.

Getting good PDF output from KiCad in Linux

kicad-appicon-128
Update: Turns out SVG might be a better base than PostScript for this. See PDF output from KiCad in Linux from SVG.

I’ve tried to get decent PDF output from KiCad‘s Eeschema a few different ways, but what I’ve found to work most reliably is to first export to PostScript (File > Plot > Plot PostScript) and then use the ps2pdf command from ghostscript to convert to PDF. (The Arch wiki has a good writeup on ps2pdf.)

The biggest problems with this are:

  1. It’s a lot of typing to get the conversion to happen (the minutia of which you won’t have memorized).
  2. It leaves you with both a PostScript and a PDF of the document(s), one of which is likely to get out of sync with the other, which may or may not be in sync with the actual schematic, etc.

To help with this, I use the script below. I drop a copy of it into the root of my KiCad projects and edit the OPTIONS as needed for the project. Then whenever I want PDFs of my schematics, I export PostScript from Eeschema and then click on this script in my file manager. Note that running this script will destroy any *.ps files in the directory—that’s by design.

#!/bin/bash

# DESTRUCTIVELY convert all postscript files
# in working directory to PDF.
# Requires ghostscript.

# Mithat Konar 2013 [http://mithatkonar.com]

OPTIONS="-dOptimize=true -sPAPERSIZE=11x17"

FILES=$(ls -1 *.ps)

for file in $FILES
do
  ps2pdf $OPTIONS $file && rm $file
done

I’ve not tried the script on any PostScript files other than those produced by Eeschema, but I’ve got no reason to think it won’t work on other PS files as well.