Many times when I run into buggy software and peek under the hood I notice that the design is convoluted and confused. There are modules with cross-cutting concerns, there is no obvious flow for the inputs and outputs, and there is no set of core abstractions that everything else builds on.
Now compare this to something that is well designed. There is usually a core set of abstractions and associated operations for building up larger computations to accomplish a goal and the rest of the software is built upon those core components. Parser combinators and optimizing compilers are good examples of such software. The flow of the computation is obvious because there are explicit and clear steps that transform high level abstractions and operations into successively lower level ones until everything is expressed by the core set of abstractions. So to understand the whole you just need to understand the core components and how they are combined. There is no reason more general applications can not be built this way. In fact most enterprise architectures with their layered approach are trying to do exactly this but fall short for one reason or another.
You just need to think of the argument array as a stream of events and the parsing logic as the state machine that responds to the incoming events. Continue reading
Most software shops these days use github or some other variation of git as a service and integrate with any number of CI as service pipelines to do testing and general sanity checking. This is fine except most places do it at the wrong level of granularity by using pull requests. Continue reading
Logging to sockets is better than logging to files. It allows for more flexibility in terms of log rotation and data integrity. I started looking around for examples of this but everything these days when it comes to logging is built for the enterprise. The actual skeleton of what all those enterprise systems are doing is quite simple. In fact it is so simple that you can do it in less than 30 lines of code in most high level languages. Here’s the skeleton for a logging server in Ruby: Continue reading
Given that you can now deploy a ruby interpreter that won’t make experienced system administrators cry the next logical step is to do the same for your ruby applications. Fortunately bundler takes us almost all the way there with its ability to vendor dependencies. All you need to do is automate the process with a few rake tasks and you are pretty much good to go. Continue reading