A Groovy approach to npm-gate

Recently the JavaScript community experienced a serious disruption when a developer removed one of his deployed libraries from the central npm server, an event now being referred to as npm-gate. I don’t want to get into the various ethical, moral, or legal issues about that here. Rather, I want to show how trivially the missing functionality can be supplied using Groovy.

The chaos came from a function known as left-pad. All the function does is take a string, a number, and a delimiter, and returns a padded string of the requested length using the supplied delimiter. Here are the examples shown on the home page:

leftpad = require('left-pad')

leftpad('foo', 5)
// => "  foo" 

leftpad('foobar', 6)
// => "foobar" 

leftpad(1, 2, 0)
// => "01"

As you can see, there’s not much to it. The implementation is pretty simple as well:

module.exports = leftpad;

function leftpad (str, len, ch) {
  str = String(str);

  var i = -1;

  if (!ch && ch !== 0) ch = ' ';

  len = len - str.length;

  while (++i < len) {
    str = ch + str;
  }

  return str;
}

The Groovy implementation is almost trivially easy, because the Groovy JDK already has a method in the String class called padLeft.

assert 'foo'.padLeft(5)    == '  foo'
assert 'foobar'.padLeft(6) == 'foobar'
assert '1'.padLeft(2, '0') == '01'

It’s easy enough to make a method out of this:

String leftPad(s, len, ch=' ') {
    s.toString().padLeft(len, ch.toString())
}

assert '  foo'  == leftPad('foo', 5)
assert 'foobar' == leftPad('foobar', 6)
assert '01'     == leftPad(1, 2, 0)
assert ' null'  == leftPad(null, 5)

So far, so good, plus it’s also a nice example of specifying a default parameter in a method.

Of course, providing a function like that to JavaScript developers doesn’t really help, because they can’t invoke it (easily) from JS. Might as well make it a RESTful web service, then. I made a Ratpack app and added a ratpack.groovy script:

import static ratpack.groovy.Groovy.ratpack

ratpack {
    handlers {
        get() {
            String s = request.queryParams.string ?: 'hello'
            String len = request.queryParams.num ?: '5'
            String delim = request.queryParams.delim ?: ' '
            response.send s.padLeft(len.toInteger(), delim)
        }
    }
}

All the query parameters are strings by default, but I wanted to make sure they all had values. Thus the series of Elvis operators to provide defaults. Next I went through the simple series of hoops necessary to deploy the app to Heroku, so I can access it using HTTP:

> http leftpad.herokuapp.com

hello

> http leftpad.herokuapp.com string==foo num==5

  foo

> http leftpad.herokuapp.com string==foobar num==6
foobar

> http leftpad.herokuapp.com string==1 num==2 delim==0

01

To make the HTTP requests, I’m using httpie, which is my standard curl replacement. Feel
You can use curl, or just type a URL like

http://leftpad.herokuapp.com/?string=foo&num=8&delim=x

into a browser to see the results.
Normally at this point I would make some kind of joke lamenting how so many JavaScript developers needed an online, downloaded dependency just to pad a string, but I won’t. After all, coding in JavaScript is its own punishment. I’ll just note that, yet again, Groovy made something trivial that apparently other languages have to work to do.

About Ken Kousen
I teach software development training courses. I specialize in all areas of Java and XML, from EJB3 to web services to open source projects like Spring, Hibernate, Groovy, and Grails. Find me on Google+ I am the author of "Making Java Groovy", a Java / Groovy integration book published by Manning in the Fall of 2013, and "Gradle Recipes for Android", published by O'Reilly in 2015.

One Response to A Groovy approach to npm-gate

  1. Ted Vinke says:

    Great writeup, Ken! 😄

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: