Archive for December, 2009

Finding Dependencies for Erlang Code

// December 17th, 2009 // Comments Off // Uncategorized

There was a short but lively discussion on the Erlang Questions list today about Makefiles and building Erlang projects.  It included a link to an interesting document on Recursive Makefiles.  In that document, I noticed an interesting tidbit that I’ve never thought about.

When building big Makefiles, you want accurate (but automatic) dependency information.  To make this easier, some C compilers (notably gcc) have a "-M" option.  Given this option, the compiler will create a file (usually with .d extension) containing Makefile code linking each file to its dependencies.

This is handy, since it would be a pain to parse C and C++ files for included files.  Getting the include paths correct would be difficult as well.  By running through all of the files once with -M (and generating appropriate dependencies for the .d files as well) creates a system whereby make can maintain its own dependency information.

I find this neat.  In fact, since this system is very nearly as old as I am, I find it extra neat.

Sadly, the Erlang compiler doesn’t have a facility to automatically generate dependencies.  That said, the Erlang compiler is written in Erlang, and most of its internals are exposed.  It seemed, then, that it would not be too much trouble to use those internals to generate the dependency information I wanted.

Ignoring, a particularly sadistic list comprehension that I had to decipher, it wasn’t too much trouble to put the pieces together.  Thus, I present you with a rough escript that will generate dependencies for a list of Erlang source files.  Despite Erlang’s verbose nature, it clocks in at 50 lines.  Not too shabby!

You can download it at:  http://needlesslymessianic.com/files/erl_deps

I don’t know about you, but I think this is pretty cool.  I think it’s most cool because you have all of the flexibility you get having a self-hosted language (like C, PyPy, and Rubinius; unlike CPython or Matts Ruby), but all of the introspection that you get in a dynamic language.  Being able to use the same functions that the compiler uses is very powerful.

Anyways, enjoy.  Comments welcome.

gen_server With Rotating List

// December 15th, 2009 // 3 Comments » // Uncategorized

For those of you who didn’t go to SF Erlounge, it was a blast.  In addition to getting to hear Tom Preston-Werner’s exciting presentation on BERT, BERT-RPC, and the new GitHub architecture, I also got to meet quite a few people who are interested in Erlang, but don’t have a lot of experience.

The great thing about these people is that they are great at bringing simple (for me) problems.  One of these problems was so simple that it occurred to me to write it and post the source.

This particular problem is dead simple.  He wanted to be able to have (possibly many) workers retrieve values from a list, rotating the list on each step.  Using gen_server to serialize the requests was obvious, but I also think that this is a great example that illustrates how gen_server can be used to wrap useful, functional (i.e. tail-recursive) code.

Have a look at the source.

It’s a simple gen_server that maintains two lists as its only state.  The first list is a list of "fresh" entries, and the second is a list of "stale" entries.  All it does is retrieve entries from the fresh list, one at a time; returns them to the user; and then accumulates them in another list of used entries.

When the fresh list would become empty, it returns the value to the caller, then automatically reverses the stale list (with the last value).  This is a minor optimization so that clients don’t have to wait on lists:reverse/1 unless absolutely necessary.

The demos each contain a start function, and the data they use is just the module list as managed by the code server.

To compile this, just use erlc on each file, or run erl -make with them in a directory.  To run them, try something like "erl -s demo_slow start".  You’ll need to kill the VM to stop it (use ctrl+c to break out and q to quit).

 

Using Ports to Communicate With External Programs

// December 10th, 2009 // Comments Off // Uncategorized

A rather nice fellow on the Erlang Questions list has been having some trouble with communicating with an external Java program.  Now, I’m not sure what he’s trying to do, exactly, but I thought that a good example is in order.

I wrote two programs to help with this.  One of them is an Erlang program (and escript, actually) that runs the second program.  The second program is supposed to, in his case, be the Java code he wants to chat with.  In my case, it’s a shell script that reads two lines, then prints out various things (including the data it was given, a random number, and the command line).  For added measure, it exits with an exit status of 42.

Thus, this example shows how to do the following core activities:

  • open an external program with port_open/2
  • write to an external program with port_control/2
  • read from that external program by receiving messages
  • use line-mode framing to receive whole lines of data

In addition, I’ve spiced it up a bit with some other useful tidbits:

  • collect a return status from the process
  • searching the path for your program
  • using spawn_executable to have strong control over your arguments
  • specifying an arg0 for those commands that need it (busybox, I’m looking at you)

Hopefully this is a help to all of the people who have been struggling with it.  Here’s a link to the code.

There are two final things that you should know.  First, if you need to move lots of data, using {packet,N} and binary are probably the way to go.  Second, if the program you’re running wants STDIN to close, there doesn’t seem to be any way to do this using a port.

Hello World!

// December 9th, 2009 // 1 Comment » // Uncategorized

Well, I founded a marginally successful Ruby startup, and I have no hardcore tech blog.  WTF?  How did that happen?

Let’s rectify that immediately.  Attention world!  I’m a hotshot Rubyist.  Read my words and fear me!

This is an opinionated community, filled with big ideas, big egos, and edgy san-serif fonts.

Look forward to various things Ruby, Erlang, Linux, etc.  Oh, and the forecast is cloudy, so make sure to put on your galoshes.