Recreating a failed Github Release with the same tag

So Reactist is configured to automatically build & publish an npm package when a new Github release is made. Over last week, I made a couple of releases, and both times I screwed up the build initially because I didn’t have everything necessary for a successful build in dev. It’s a bit tricky to re-trigger the Github action again for the build, as a re-trigger will just rebuild from the same (old) Git commit. Here’s what you have to do instead:

  1. Delete the tag using: git tag --delete name && git push --delete origin 4.0.1
  2. Now, refresh the releases page, and you’ll notice that the earlier release will now be marked as a Draft Release.
  3. Delete that release, and make a new release with the similar information, and make sure to create the same tag.
  4. Now, the GitHub Action will run again, and will hopefully succeed. It does leave some orphan builds in your GitHub Actions list, but that’s not a big deal!

Mouse Wheel Handling in Prototype/Javascript

Here’s how to handle mouse wheel events in prototype, code heavily borrowed from other places on the net, but brought together and made unobtrusive:

/* Mouse Wheel */

Object.extend(Event, {
	wheel:function (event){
		var delta = 0;
		if (!event) event = window.event;
		if (event.wheelDelta) {
			delta = event.wheelDelta/120;
			if (window.opera) delta = -delta;
		} else if (event.detail) { delta = -event.detail/3;	}
		return Math.round(delta); //Safari Round

SetupMouseWheel = {
	initialize: function() {
		Event.observe(document, 'dom:loaded', this.setup_mouse_wheel);

	setup_mouse_wheel: function() {
		Event.observe($('element'), "mousewheel", function(e) { SetupMouseWheel.handleDiv(e) }, false);
		Event.observe($('element'), "DOMMouseScroll", function(e) { SetupMouseWheel.handleDiv(e) }, false); // Firefox

	handleDiv: function(e) {
		direction = Event.wheel(e) < 0 ? leftSeek : rightSeek;
		console.log(direction); //handle scroll
		direction(); //call leftSeek or rightSeek depending on direction.

The problem with this code though, and the reason I haven’t found a productive use for this yet is that the browser always scrolls the viewport when it extends beyond screen dimensions. So you have your scroll handler and the browser’s scrolling viewport playing hanky-panky, and it’s not a good sight to see. For applications which always stays within the browser window though, this is useful code.

Self-labeling text entry INPUT boxes using Prototype JS

Like previous code snippets, this one is mostly all code and no explanation.

A brief primer: you’ve often seen self-labeling input boxes, the ones that display a label inside in gray text, and when you click replaces with an empty input element using Javascript. This is a simple class to help you achieve that effect:

SelfLabelingBox = {
	initialize: function(box_id, message) {
		this.setup_behavior(box_id, message);

	setup_behavior: function(box_id, message) {
		box_id = $(box_id);
		if(box_id) {
			if(box_id.value == '') {
				box_id.value = message;
			Event.observe(box_id, 'focus', function() {
				if(box_id.value == message) {
					box_id.value = '';
			Event.observe(box_id, 'blur', function() {
				if(box_id.value == '') {
					box_id.value = message;

SetupDefaultInputs = {
	initialize: function() {
		Event.observe(document, 'dom:loaded', this.setup_default_inputs);

	setup_default_inputs: function() {
		SelfLabelingBox.initialize('search_text', 'Search');

Until next time!

IP Address to Country in Erlang: ip2country-erlang

Inspired by the latest Ruby Quiz: IP to Country: #139, I coded up a utility to map ip addresses to country codes in erlang. It’s available on google-code at

Some experiences while making this thing work:

  1. It took me the better part of six hours to get this running. I suspect if I’d done this with Ruby, I’d have completed an elegant, fast solution in less than a half hour. However I did make this harder for me (see below).
  2. It uses the in-memory database that Erlang has: mnesia. There’s functions in there to populate the mnesia table with the csv file and then perform lookups on it.
  3. Higher-order functions is the name of the game. For just about every useful thing from looping down to iteration, to mapping elements of a list. Coming from a non-functional background, I find this very hard to grasp still. Also: non-mutable state. Count +=1 doesn’t work. [So how do you implement a counter? Recurse with a parameter].
  4. I miss the Ruby Standard Library very very badly. Of all the languages I’ve used, Ruby’s is the most concise and clear and manages to have just about every function you need in there. String manipulation in Erlang esp. is very cumbersome. Somebody probably should port over all the functions asap. lists:join, string:delete, string:delete_if etc. would be invaluable.
  5. The comma, semi-colons and fullstop craze (along with proper indentation) is sometimes very confusing. The rules are actually easy to remember, but when I nest functions using funs, I find I lose track of where I am and what’s supposed to happen. I started programming this using Aquamacs but it crashed on me midway while using the inbuilt shell. I hate stuff which crashes so I switched to Textmate’s erlang mode which isn’t as functional but does a decent job of parenthesis matching and auto-indent.
  6. Mnesia is a joy to use. I spent a lot of time just playing around with many examples because it’s fun to make a record, dump it and use list comprehensions to perform selects. It’s way more intuitive than using SQL. Witness this fragment:
      qlc:q([X#ip_address_map.country_code || X <- mnesia:table(ip_address_map),
    		     X#ip_address_map.range_from =< Ip_address_as_integer,
    		     X#ip_address_map.range_to >= Ip_address_as_integer

    That actually just says: get the country code for all X where X is an mnesia table of type ip_address_map and where X’s ip_ranges are within range_from and range_to. No SQL and exactly as you’d do within the language.

  7. It feels very awkward to get Erlang to be a shell scripting language. I’m not sure escript is even supported anymore but it does work. Erlang is not for scripting.
  8. The whole exercise reminded me of my extreme newbiness. I’ve been dabbling off and on in Erlang for over four months now and still I’m not at a stage where I can code in it off the top of my head (this hasn’t happened before with any language, but admittedly all the others were just procedural ones). The problem is I’m not using it for anything big. That should hopefully change someday. [Not much hope, but does somebody want to hire me to work on erlang or lisp? :-)]
  9. The erlang mailing lists help a lot. Just being there you soak up a lot of info.
  10. Concurrent erlang is another ball game altogether.

Get started!