Dialyzer Warning: Function has no local return

September 10, 2009

This one is tricky. I’ve been working with dializer and typer on coverize and hit the following warning from dialyzer:
coverize.erl:13: Function run/2 has no local return

Seems like it would have something to do with the return types. Right? Certainly seems like it would be. After searching, experimenting and trying everything I could think of with setting the return, luck bestowed upon me the following link: http://zerthurd.blogspot.com/2009/05/dialyzer-warning-no-local-return.html .

After about 3 seconds of staring at the following code, it hit me.

-spec(run/2 :: (list(string()), atom()) -> ok).
run(SourceDirs,TestSuiteModule) ->
  CompileOptions = [ debug_info,
                     { i, "./include" },
                     { outdir, "./ebin" }],
    run(SourceDirs,CompileOptions,TestSuiteModule,"./coverage").

-spec(run/4 :: (list(string()), list(atom()|tuple()), atom(), string()) -> ok).

Look closely at the values in CompileOptions. Tuples -yes, then AHA! – debug_info is an atom().
The correct spec should have atom() as an alternative in the second parameter.
Here’s the corrected version
-spec(run/4 :: (list(string()), list(atom()|tuple()), atom(), string()) -> ok).

Dialyzer is now happy!

What a huge waste of time to figure that one out. Dialyzer needs better messages for this


Bash Prompt with Git/Svn info

August 18, 2009

While looking for emacs stuff, I stumbled on this post about integrating scm info into the bash prompt.
I knew I was irritated by always typing “git status” in svn dirs or “svn st” in git dirs because I have so many of both but never got motivated to do anything about it. Thanks to Christopher Sexton for this one.
What a timesaver! Super simple to install. Here’s the link – http://www.codeography.com/2009/05/26/speedy-bash-prompt-git-and-subversion-integration.html

If on linux, just stick the first code fragment in ~/.bashrc and you’re good to go.
It shows both the git or svn revision and the current branch. Pure Awesomeness!


Accessing Erlang Records In List Comprehensions

August 3, 2009

Accessing Erlang records in List Comprehensions can be really useful when you want to keep the amount of typing down to a minimum yet retain readability in a compact format.
In my rather feeble attempt to participate in the 2009 GitHub Contest, I’m accessing and manipulating records quite often and using list comprehensions is a natural approach.

Let’s jump to some code to see something interesting. This is a little test program to see two different ways to access record elements in a list comprehension which I tend to use a lot.


module(test).
-compile([export_all]).

-record(detail, {id, name}).

run() ->
DetailList = [
#detail{id=1},
#detail{id=2}
],
% 2 different ways to access an element of record in a list of records
Result1 = [ ID || _X = #detail{id=ID} <- DetailList],
Result2 = [ X#detail.id || X <- DetailList],
io:format("Result1 ~p~n",[Result1]),
io:format("Result2 ~p~n",[Result2]).

Result1 and Result2 are [1,2] which is just the id values from Detail List. The list comprehensions are equivalent but there’s a trade-off that I consider when using them.

The second method is more obvious and shorter when it’s just one value to deal with. When there are several values that you want to pull from the
list, using one pattern is cleaner for understanding the values going into the result.

For example:

Result1 = [ {ID, Name} || _X = #detail{id=ID, name=Name} <- DetailList],
vs.
Result2 = [ {X#detail.id, X#detail.name} || X <- DetailList],


In this example, the values extracted in Result2 become obscured by the record extraction noise(X#detail).
and it takes more effort to read than simply {ID,Name}.

I’ve not benchmarked it but I believe that if there are several values to extract, the
single pattern match is faster than accessing each one separately with the dot (“.’) notation.


erlang-cheat Released

February 17, 2009

I really like the Cheat Sheets on http://cheat.errtheblog.com but I wanted to access the sheets from inside the erlang shell.  The basic code for erlang-cheat was written last year but I finally got around to cleaning it up for relase on github.  It works equally well when running an erlang shell within Emacs and makes grabbing cheat snippets a breeze.

erlang-cheat is available with my other
releases at http://github.com/mmullis

It’s just the client side since I had no intention of hosting a separate cheats site. The current code will share the same cache as the cheat rubygem so it doesn’t impose any extra burden on the source site.

The structure is there for adding eunit tests but since it’s mostly for developer use, there’s nothing of substance yet.

Happy Cheating!
michael


Softlinks and Erlang Libs on Windows

January 28, 2009

Erlang + cygwin on Windows does NOT like softlinks for libraries.

On linux, I use softlinks in erlang/lib for projects I’m working on and tracking in another location.
This practice seems to be problematic on Windows so just dont do it.

It took a bit to figure out so I hope it helps someone else save the time I lost.


Macaddr For Erlang Released

September 23, 2008

Ah. My first real Erlang effort presented for all to see – http://github.com/mmullis/erlang-macaddr.

It started with the goal of porting the macaddr gem for ruby. This is all on R12B-4 so keep that in mind. Macaddr basically runs an os specific command like ifconfig or ipconfig and attempts to extract out the mac address information from the resulting spewage using a regular expression. There’s quite a few posts about how this is not available in Erlang and that the undocumented inet:ifget and inet:getiflist are not really portable. I hope someone finds it useful.

Ok, so it’s nothing hard in Ruby but Erlang ended up being more difficult. Mostly due to the new re module not being quite the same. I also had to break the code up a bit more in order to isolate different aspects. I’m not an Erlang guru either so there’s probably some dumb code in there and optimizations needed.

Two things I learned in the process of dealing with the re module.  The first is that it is based on PCRE underneath. To help in debugging, I built the PCRE packakge using the source which is tar.bz2 in the OTP release. PCRE includes a program called pcretest that will let you run regexes with different data. It’s easy enough to figure out. What you do is validate that PCRE is handling a regex the way you want, and then back up into Erlang.

The second thing I learned is that you have to escape ALL backslashed expressions/assertions so that they pass through Erlang unmodified and get to PCRE. I was trying to use “\b” which is word boundary but it never made it down to PCRE correctly untill it hit me and I tried “\\b”. Eureka! (yes, one of my favorite shows).

The doc for re has a really small blurb in the replace function doc. Too hidden for me so I sent a request to the  erlang-bugs mailing list to make it really clear.

The real time consumer was that the regex that worked fine on windows and linux broke down on macos where there’s a much longer sequence of “nn:”.  This resulted in the exporting of an internal function so I could test it more readily.

Overall, I think it took longer than I would like a small project to take but I’m picky and wanted to make it reasonably complete with Makefile, eunit tests,  git hosting on github, Readme, edoc, clean dialyzer, testing on 3 different platforms (Linux, Windows Vista, and Mac OSX). It should be a decent structure for my next project.


mnesia and eunit

September 16, 2008

I’ve been working my way through Kevin Smith’s Erlang In Practice screencast series and decided to write some eunit tests for episode 6 (covering Mochiweb).  The plan was to do a basic test which would register a nickname, then register the recipient which would also send back the waiting message and give me a chance to compare it with the original message.

Well, it took a LOT longer than it should have. The tests were inconsistent and would fail often but not predictably. Reworking the tests and underlying code didn’t yield much help. Debugging and tracing were not helpful either. There’s some timeouts in mochiweb or the http handling that are triggered when stepping through the code in the debugger. The get on the right track, I created a more specific test for the message_store.

Eventually it became clear that mnesia:start has some delay and that the unit tests run so fast that accessing the table becomes a race. If mnesia cannot see the table yet when we try to read the table, there’s an error that looks like this

{badmatch,{aborted,{no_exists, chat_message}}}

I wrote some code to wait for the table to become available and then I came across this post – http://rakuto.blogspot.com/2008/07/erlang-tips-sometimes-to-call.html.

Apparently, there is already a function in mnesia to handle this. So, all we need is

mnesia:wait_for_tables([chat_message], 3000),

There’s a couple of places it can be used.  The first is in each mnesia transaction but this would be overkill. The problem only surfaces when mnesia:start is called but the tables are not ready for use so placing it right after mnesia:start seems reasonable.

In message_store.erl:init_store add the following line right after mnesia:start() and all should be good.

mnesia:wait_for_tables([person], 3000),

Hooray! Now the message_store tests run consistently and I can move on with the overall tests.


Forked over by rspec

September 10, 2008

I’ve been working a a ruby project using rspec for the tests and I got stumped pretty good today. The symptom was that tests would randomly fail for a variety of reasons. Many were because temp files were disappearaing. I decided to spend some time refactoring the tests first to get things a little cleaner and this helped a little.  The symptom that became more obvious after rework and putting some debug “puts” in was that at a random point, the tests would start duplicating. Adding a semaphore/Mutex didn’t make any difference. Same test, same thread, same mutex. Still duplicated.

After a lot of digging and searching for problems with rspec, rcov, rake and their interactions I came across this post – http://blog.hiremaga.com/2008/01/31/dont-get-forked-by-rspec/ .

There was indeed a test that was calling a class that daemonized itself by calling fork. Unfortunately changing the at_exit as suggested does not work in my case.  Adding a boolean to allow skipping the fork during testing works sufficiently to keep rcov happy.

All tests green again.


Aspire One On Order

September 5, 2008

Pre-Ordered the Aspire One today from Amazon. I decided to get the 6-cell version with XP (blue sapphire if you care) and plan to set it up with a Linux distro. Not sure if I want to dual boot or just replace XP completely. I’m a little worried about the drivers and any questionable hardware inside that might affect a linux install,
I know Ubuntu should run but I’m thinking a smaller distro like DamnSmallLinux or PuppyLinux will be more fun.
I’d also like to get E17 running on it, git, emacs, and erlang OTP running on it.
Downside is that it wont ship until EOM September 2008 + a week for delivery. MicroCenter has the $349 version and I really need something to carry around but it’s 3-cell. For 50 bucks, jumping up to the 6-cell and double the battery life is a much better deal.
Not sure I can be patient.


Starting Over. Again.

September 5, 2008

Title says it all – as far as blogging goes. I’ll try to stay focused on tech topics that interest me and maybe a few people will be interested.

As far as the blog title is concerned, I have this problem that my face makes me look angry when I’m just ambivalent or uninterested. It sucks. There is some evidence that I am in this small percentage of the population that has this problem. We don’t look happy, perky or excited when we really are.
Learning to force a big smile more often is difficult but I’m working on it. A wide face and big head (really) don’t help.
So if you ever meet me, please assume that I am very excited to meet you and promptly forget what my features may convey.

Thanks!
michael.