Saturday, June 12, 2021

handy makefile script

I frequently find myself looking for default make rules, and inevitably how to print their values.  Here's a script to help.

Adapted from https://blog.melski.net/2010/11/30/makefile-hacks-print-the-value-of-any-variable/

$ cat ~/bin/make-vars 
#!/bin/bash

_vars=
for v in $@; do
  _vars="${_vars} print-${v}"
done

make -f- ${_vars} <<'EOF'
print-%:
	@echo '$*=$($*)'
	@echo '  origin = $(origin $*)'
	@echo '  flavor = $(flavor $*)'
	@echo '   value = $(value  $*)'
EOF

Here it is in use

$ make-vars LINK.cc
LINK.cc=c++    
  origin = default
  flavor = recursive
   value = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

Friday, June 4, 2021

New home for joinery

As of version 1.10, joinery is now hosted in the central repo using the sh.joinery groupId.

As part of the move to central, joinery also has a shiny new domain https://joinery.sh.

Friday, July 10, 2015

pipelines and functional java

Mr. Fowler has written a nice series on using pipelines instead of iteration for processing collections.

On a similar note, I recently came across this presentation on reactive programming in Java which also notes the benefits of composing operations as pipelines (though with a particular focus on processing sequences of observable events since this is reactive java after all).  If you read through the deck to the last slide, you'll notice a humorous meme which represents more concisely Fowler's main point.

I'm so glad this exists.

Obviously, as shown in my Joinery project, I'm a big fan of this programming style.  It provides a powerful mechanism for expressing the kinds of operations that are required when operating on large amounts of data while yielding a very high signal:noise ratio when reading the code.

Friday, September 21, 2012

apache zookeeper status with bash

Most Apache ZooKeeper users are familiar with ZooKeeper's four letter words. And many bash users know that recent versions of the popular shell can redirect to network ports. But I've yet to see the two used together. The other day I found myself without netcat and looking for a quick way to get stats out of ZooKeeper. A short bash function later and I can easily check on ZooKeeper from any shell (so much quicker than spinning up a JVM).
zk4 () 
{ 
    echo "${2-localhost}:${3-2181}> ${1-ruok}"
    exec 3<> /dev/tcp/${2-localhost}/${3-2181}
    echo ${1-ruok} 1>&3
    cat 0<&3
    [[ ${1-ruok} == "ruok" ]] && echo
}
Usage is simple, by default it will issue the ruok command to localhost on the default port 2181. But you can specify alternate values for each of the host, port, and command parameters.
zk4 stat
zk4 srvr
zk4 ruok zk-server1.myco.com 20181

Tuesday, March 1, 2011

Monday, February 21, 2011

a quick review

In lieu of actual new content... a quick recap of some good posts from several of my favourite sources:

1. Steve Yegge's excellent post on code, code base size, and perhaps a reason to use rhino - http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html

2. Reginald Braithwaite's writings on code style and why clarity is king - http://weblog.raganwald.com/2007/12/golf-is-good-program-spoiled.html

3. Hamlet D'Arcy's humorous article on the detriments of new found functional programming knowledge - http://hamletdarcy.blogspot.com/2009/08/how-to-tell-your-co-workers-have.html

There you have it, just in case you missed 'em the first time around.

Saturday, August 14, 2010

getting reacquainted with javascript

Ok, I'm admittedly a little late to the party here. Lots of people are doing really, really cool things with javascript these days.

So, I've been using rhino to whip together my java experiments lately. Setup is trivial, you just need java and js.jar.

  1. download rhino 
  2. extract js.jar (at least)
  3. for an interactive shell, run java -jar js.jar
  4. or run a script using java -jar js.jar some-javascript-file.js

Once you have rhino, all sorts of java-ish things can be whipped up as quick hacks.
A quick http server, for example, goes something like this:

function main() {
  var s = new java.net.ServerSocket(8080)
  while (true) {
    var client = s.accept()
    var sc = new java.util.Scanner(client.getInputStream())
    var method = sc.next()
    var path = '.' + sc.next()
    var out = new java.io.PrintWriter(
            new java.io.OutputStreamWriter(client.getOutputStream()))
    try {
      var f = new java.io.FileInputStream(path)
      out.println("HTTP/1.1 200 Success")
      out.println("Content-Type: text/html")
      out.println()
      for (var c = f.read(); c != -1; c = f.read())
        out.write(c)
    } catch (e if e.javaException
        instanceof java.io.FileNotFoundException) {
      out.println("HTTP/1.1 404 File not found")
      out.println("Content-Type: text/html")
      out.println()
      out.println("<html><body>")
      out.println("<h1>File not found</h1>")
      out.println("</body></html>")
    }
    out.flush()
    out.close()
  }
}

main()

Wait, what about a threaded server you say? Try this on for size.

function main() {
  var s = new java.net.ServerSocket(8080)
  while (true) {
    var client = s.accept()
    var t = java.lang.Thread(function() {
          var sc = new java.util.Scanner(client.getInputStream())
          var method = sc.next()
          var path = '.' + sc.next()
          var out = new java.io.PrintWriter(
                  new java.io.OutputStreamWriter(client.getOutputStream()))
          try {
            var f = new java.io.FileInputStream(path)
            out.println("HTTP/1.1 200 Success")
            out.println("Content-Type: text/html")
            out.println()
            for (var c = f.read(); c != -1; c = f.read())
              out.write(c)
          } catch (e if e.javaException
              instanceof java.io.FileNotFoundException) {
            out.println("HTTP/1.1 404 File not found")
            out.println("Content-Type: text/html")
            out.println()
            out.println("<html><body>")
            out.println("<h1>File not found</h1>")
            out.println("</body></html>")
          }
          out.flush()
          out.close()
        }
      )
    t.start()
  }
}

main()

For more reading about rhino and javascript including how to structure, organize, and manage your code for larger projects, try these great posts.

http://steve-yegge.blogspot.com/2008/06/rhinos-and-tigers.html
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
http://peter.michaux.ca/articles/javascript-widgets-without-this
http://www.jspatterns.com/