Skip to main content

Posts

The Saas-pocalypse. Opportunity or doom and gloom for software as a service?

An ex manager of mine brought up the term Saas-pocalypse a few weeks ago and it was the first I heard of it. Nowadays, instead of paying for Software as a Service, you can log into an AI agent and have it build a website for you that does exactly what you (think you) want in mere minutes. As a software developer, some of it does look like magic and to be honest it does worry me to an extent. However, I don't think the role of software developer is going away, though it might be changing and I will explain why. There are some companies that are going to be affected. If your Saas has very few touch points or deep interaction with your users then you probably will not survive. But here's the thing, AI probably was not what killed your Saas to begin with. Web sites and web apps have been easy and cheap to build and prototype for quite a while now, AI, has just made it a little bit easier and cheaper (ok, a lot easier and cheaper). Just having a website is not what builds a business...

AI has killed the DSL. Long live the DSL!

(This article is pure opinion and is not based on any facts what so ever...) At present (in April 2026) not only are most programmers not writing code directly, we are not writing Domain Specific Languages directly either. A domain specific language, unlike a general programming language, is a language written to solve a specific problem. Often a DSL is translated into a general purpose language (either by interpreter or compiler) and exists to help a programmer read code and reason about a problem in a more readable way. One example that comes to mind is a Arel which is a DSL for writing SQL queries. While SQL is already quite user friendly on the surface, queries can become complex quite easily after a few joins. Also, there are slight differences in SQL depending on which database you use (e.g. Postgres vs MySQL vs Oracle) so having a DSL smooths over these changes as well. However, sometimes achieving what you want to do in Arel can be harder than doing it in raw SQL and also Arel ...

What you can and can't learn from personal software projects.

Ok, controversial click bait title aside, personal software projects do an enormous amount of good in teaching you how to learn new languages, write better code, architect code and may even make you a buck or two on the side (if you are lucky). However, there are some things that you are not likely to learn when writing personal software projects and I wanted to discuss a few of them here. What they can't teach you How to communicate your ideas By definition a personal project is personal. You are probably the only one working on it (though you can ask a friend or two to help, which is highly advisable if you can). When you want to add a new software pattern or framework, you just do it. While that's incredibly liberating, one of the benefits of working in a team is having to explain your decisions will make you more reflective and will give you a better sense of if you are doing things the right way or not. If you meet with resistance to the idea, it means you have to th...

Ecto "inheritance" using macros

Oooh them's fighting words. Anyways, this is definitely not true inheritance by any means, but let me explain the problem and then the solution. Ecto is the primary way you connect to the database in Phoenix. However, Ecto differs in many significant ways from ActiveRecord in Rails. You can set up a schema file which lists the relationships between your "models" or "entities", but these schemas do not allow you to directly access the database. They are merely descriptions of how the data is expressed. To access the database, you need to use a data context which uses Ecto. So, from my article comparing Active Record to Ecto ( http://www.skuunk.com/2020/01/comparing-rails-active-record-pattern.html ) defmodule Schema.Article do use Ecto.Schema import Ecto.Changeset alias Schema.Author alias Schema.Comment @permitted_fields [:title, :content] @required_fields [:title, :content] schema "article" do belongs_to(:author, Author) ...

Elixir - destructuring, function overloading and pattern matching

Why am I covering 3 Elixir topics at once? Well, perhaps it is to show you how the three are used together. Individually, any of these 3 are interesting, but combined, they provide you with a means of essentially getting rid of conditionals and spaghetti logic. Consider the following function. def greet_beatle(person) do case person.first_name do "John" -> "Hello John." "Paul" -> "Good day Paul." "George" -> "Georgie boy, how you doing?" "Ringo" -> "What a drummer!" _-> "You are not a Beatle, #{person.first_name}" end end Yeah, it basically works, but there is a big old case statement in there. If you wanted to do something more as well depending on the person, you could easily end up with some spaghetti logic. Let's see how we can simplify this a little. def greet_beatle(%{first_name: first_name}) do case first_name d...

Comparing Rails' Active Record Pattern with Phoenix/Elixir/Ecto

Rails has a very well established Active Record pattern for dealing with the database. You have an Active Record model which maps to the database table, the schema of the model comes directly from the database schema and you place your model specific methods on the Active Record model. This file is also where you set your model relationships (e.g. has_many, has_one, belongs_to). Your instance of the model has all the methods built in. In Ecto/Phoenix it's a little different. First of all, the database schema doesn't automatically map to the "model". In fact we don't really have models (as Elixir is a functional paradigm). What happens in one file in Rails, happens in essentially two (or more). You have a schema file (where you have to list out all the attributes and relationships). Using the schema file, your "instance" is essentially a data structure (with no methods on it). If you want to transform the data on your struct, you would use a context mod...

JavaScript on Rails 2016

Whilst I am primarily a JavaScript programmer, my framework of choice is Ruby on Rails. A lot of JS guys like Node or other frameworks which are JS all the way through, but there's a lot to like about Rails, even in 2016 and it's worth learning another language (Ruby) or two (SQL) in order to get the best environment on which to write your JavaScripts. Before I say what I like about Rails though, I will take you through what I don't like just to balance things out. What I don't like about Rails Asset Pipeline still does not let you use ES6 Modules.  Even at this late stage, one still cannot access ES6 Modules in Rails in a "Railsy" manner. You can either bypass the whole Asset Pipeline or else separate out the JS using Webpack or whatever, but in a standard Rails project, the fact that the asset is generated with unique hash in the file name before the extension pretty much nullifies its use for ES6 Modules which need a static location to store the fi...

React: Viewless components

I have been using Facebook's React library for a while now (https://facebook.github.io/react/) and I like it for the most part. The most controversial aspect is the fact that the View is mixed into the Logic using what looks like HTML in the "JavaScript" file using JSX. While it is possible to write React components in plain JavaScript, you must include a render() method. However, it is actually possible to do the following... (in ES6 syntax) render() {   return (null); } Now, why would you want to do such a thing? I thought the whole point was to use React to tie together your view and logic layers (and shouldn't you be abstracting out your heavy logic to plain JS classes?). Well, the main reason you might want to do it is because of React's component lifecycle. In my case, I wanted to trigger some JS to run when the component was loaded, and I happen to be using Turbolinks and React-Rails in a Rails project. This JS had ...

Testing React components with Jasmine in Rails with the react-rails gem

So in my latest project, we are using Ruby on Rails and the react-rails gem to implement our React components. While react-rails is fine for the most part (and for simple components), there is a severe limitation in that you cannot use ES6 modules (i.e. using the import and export classes) because of the way asset-pipeline works. Asset-pipeline precompiles all your JS into one mega JS file and therefore doesn't allow you to call individual JavaScript components in separate files (because they don't pushed to the server). This is a severe problem which I hope gets fixed soon, but in the meantime don't hold your breath. There are workarounds using Browserify and/or Webpack, but they are messy (Google them for more info). In any case, react-rails does allow simple React components in Rails apps and it mounts them all in the window/global namespace, so you can use a good 75% of React within a Rails application. So now, we come to testing... Facebook uses a testing f...

Rolify, Devise, Rspec and Capybara Webkit in Rails

So I was using Rolify, Devise, Rspec and Capybara Webkit in Rails and I ran into a problem with the Warden login_as helper when trying to do a feature spec with :js => true (if you didn't understand any of that, you are probably on the wrong blog). Anyways, while the I was able to log in an admin, Rolify was not able to determine the roles. This is in spite of the fact that I added a role in Factory Girl. FactoryGirl.define do factory :admin do email { Faker::Internet.email } password "password" password_confirmation "password" trait :administrator do after(:create) {|admin| admin.add_role(:administrator)} end end end This worked fine with js turned off, so why was it not working now? So the answer had to do with the following line in rails_helper.rb config.use_transactional_fixtures = true So I believe what happened in Capybara webkit is that it runs in a different thread and while Warden's login_as worked fine ...

Global Warming is a Year 2000 problem

Global Warming is a Year 2000 problem. What I mean is not that Global Warming has been solved (far from the case) nor that it is a problem that we could only have solved 15 years ago (though that might be closer to the truth). What I mean is that if we solve Global Warming, then people will think it was a hoax (or something we should not have worried about). Think back to the glory days of the 1990s. Media was full of stories about how all the world's computer systems were going to fail because programmers tried to save space on their systems by dropping the first 2 digits off the year field. Power stations and ATMs would stop working. Global financial crises would ensue (well, that did happen, but for other reasons...). Basically we were going back into the stone age unless we chucked large amounts of money at software developers to fix our computer systems and by and large that did happen. After we partied like it was 1999, apparently nothing happened. I am sure a couple ...

Source Location, i.e. Where the heck is this method defined?

Just a short one for now. Most of the time, if you are working on a well defined project, it's pretty easy to find where a function is if you want to change/tweak it. You can look in the class where it is defined and/or see if there are any mixins or decorators. Sometimes, it can be downright impossible to tell. Enter source_location Fire up your rails console and put in the following (for a class method :search on User) User.method(:search).source_location if you have an instance method User.new.method(:search).source_location This should give you something like the following [ "/Users/yourdrive/Projects/prokect/vendor/cache/thinking-sphinx-9b71ce0f7d9d/lib/thinking_sphinx/search_methods.rb" ,   367 ] This should at least give you some idea of what is going on...

Mixins in ES6

I had been looking for a good way to do mixins in ES6. Looks like I finally found one. http://raganwald.com/2015/06/10/mixins.html Essentially, create the mixin as a const Use Object.assign to add the properties to the Class const BookCollector = { addToCollection ( name ) { this . collection (). push ( name ); return this ; }, collection () { return this . _collected_books || ( this . _collected_books = []); } }; class Person { constructor ( first , last ) { this . rename ( first , last ); } fullName () { return this . firstName + " " + this . lastName ; } rename ( first , last ) { this . firstName = first ; this . lastName = last ; return this ; } }; Object . assign ( Person . prototype , BookCollector ); (I am copying and pasting this for personal reference in case the original site link goes down).

The perils of over testing

Test Driven Development (TDD) is a great thing. It allows us to write code "safe" in the knowledge that if we accidentally break something in another part of the system, we will be alerted to it and can re-write or fix accordingly. It's such a good thing that often in large teams people will insist on this idea of 100% code coverage (i.e. every piece of working code has a corresponding test). Also, some people are compelled to test every single permutation and variation of how someone will access their program/website. TDD does have some costs however. Some are evident, but others not so. Cost 1 - Tests take time to run True, automated testing is faster than manual testing, but they do take time to run. This time means every time you make a change to the code, you need to wait for the suite to finish running in order to feel that your code is "safe" for deployment. Most of this time is a necessary evil. A lot of it is unnecessary... Should you write...

ECMAScript 6

Today is a rather significant one for me as JavaScript/Rails programmer because Sprockets ( https://github.com/rails/sprockets ) upgraded to version 3 meaning I can now use the Sprockets-es6 gem ( https://github.com/josh/sprockets-es6 ) to transpile ES6 JavaScript to ES5. Now to those that didn't understand the last paragraph, here's what it means... The language we commonly call JavaScript is actually formally known as ECMAScript ( http://en.wikipedia.org/wiki/ECMAScript) . Since 2009 all the major browsers have been interpreting ECMAScript version 5. In fact they mostly still do. Version 6 is due to be formalised any day now (well, June 2015) which means that a whole new slew of functionality is due to be added to the language (class constructors, formal inheritance, fat arrows, etc...). Browser makers will start implementing these new features once the spec is complete. All of this sounds great, but for 2 things 1) I want to start using ES6 today 2) Even if the ne...

Opal - Ruby to JavaScript compiler

So I just found out about the Opal Ruby to JavaScript compiler and I am very intrigued. http://opalrb.org/ So for a few years now, the Ruby community has been encouraged to use CoffeeScript as a JavaScript "alternative" ( http://coffeescript.org/ ) but for some reason, as an avid JavaScript programmer, it never appealed to me. CoffeeScript offers a small amount of syntactic sugar on top of JavaScript, but it never seemed worth the learning curve for me to take it on. I don't actually mind JS's brackets (as they let you know where things begin and end cleanly) and significant white space in a programming language has always seemed like a bad idea too (it's bad enough that a misplaced semicolon can stop a program from running properly, but try searching for an extra white space character you can't even see!). Opal on the other hand, is actually Ruby compiled to JavaScript (not Ruby/Python-ish syntax). It looks, feels, and even smells like Ruby because it i...

Checking performance in EaselJS apps

So one of the great things about EaselJS  is the fact that you can create Flash like games in JavaScript. I have been doing so on www.activememory.com for the last couple of years. Unfortunately, it came to our attention that on some systems, the games ran rather slowly. According to their own docs, they admit that the time between ticks might be greater than specified because of CPU load ( http://www.createjs.com/Docs/EaselJS/classes/Ticker.html#method_setInterval ). So, is there any way we can track the actual time between ticks on a real system? Fortunately, yes, we can. On each element that uses the ticker, you can set up an addEventListener and set the method you want to fire on that interval. createjs.Ticker.addEventListener('tick', tickListener); In the method itself you will want a few instance (or global) variables this.previousFrameTime this.totalFrames this.totalFrameTimes as well as a local variable currentFrameTime On each tick, we get the cu...

Our git workflow

In my current gig in ABC Active Memory ( https://activememory.com/ ) we have put together a git workflow which works really well for us, so I decided I would write about it here so that others could benefit. The things you need to have in place though are Continuous Deployment ( http://en.wikipedia.org/wiki/Continuous_delivery ), Test Driven Development ( http://en.wikipedia.org/wiki/Test-driven_development ), Agile ( http://en.wikipedia.org/wiki/Agile_software_development ) and the desire to keep releasing small independent incremental features without any one of them blocking each other. Branches So the key is branches (obviously). We have 2 main branches which are shared by everyone, and every new feature takes place in a feature branch.  Our 2 shared branches are  acceptance master Feature branch When we start a new feature, we do all the work in our feature branch which we cut from  master . Our feature branches are named by ticket number (i.e...