Monday, 9 July 2018

Reasoning with SOLID Principles: Single Responsibility

The SOLID Principles are a great tool to help you learn object oriented principles, but after trying to apply them for quite some time I think there are definite boundaries to when and where they should be applied.

I'll break this into parts! here is part 1!

Single Responsibility Principle

Single responsibility is a great tool for quickly noticing when you've got too much stuff in your stuff, if its obvious that there are two very different responsibilities in an object it can be worth separating them to make things clearer. The issues you hit with this really as you have to be careful about thinking what abstraction level you are reasoning about when considering this.

Say I have an Order object, my order object contains things that are order related, perhaps and ID for the order and some methods to update the order and send the order. But if someone ended up adding a method that draws an alert to the UI, this perhaps would stand out.

get_order_id()
update_order()
get_order_items()
draw_ui_alert()
I wouldn't normally name like this, just trying to make it clear that all the methods apart from the draw_ui_alert clearly relate to the order.

Perhaps I add a method to print the order, to start this method is small and just outputs the order id, this makes sense within the SRP right? The responsibility of the object is to manage the order, the responsibility of the print function is to print the order. We can see that if we were to make the print function also add a new item to the order that this could be a violation of the principle. But what about when the print method grows very large because it also includes a lot of code that describes how printing works, not necessarily related to the printing of the order.

Is there two responsibilities there sounds like it, but when that code was smaller it didn't feel like there was, so surely the principle has to be used in conjunction with balancing the size of things. So now we look at our print method the first line initialises a printer object... well thats a single responsibility depending on the abstraction level we are thinking about right, being responsible for adding a and b together could be a single responsibility. I'm not hating on the principle, just that it sounds like a simple rule but in practice is much more a great tool for reasoning about if something does too much, or how to split it when it is too large.

I guess for quite a few of the principles that is the key, knowing when to apply them and how. But also just using them as thought tools :D

Sunday, 8 July 2018

Git Bisect Scripting!

So sometimes you want to find out what commit a bug was added, even if you have tried git bisect its a pretty manual thing doesn't seem too cool. Let's just go over the basics for anyone who hasn't used it before.

Bisect basically allows you to do a binary search over a git history to find when a bug was introduced. To start you will need a known bad commit (normally the latest, or a released version) and good commit, probably the commit the feature was added in when it was working all well and good :)

First enter bisect mode
git bisect start [BAD] [GOOD]

you can use all the usual allowed stuff (branch, commit#, HEAD~2, whatever)

Then manually check if the commit is good or bad and report!
git bisect good
git bisect bad 

Also if the project does not build or something you can skip one!
git bisect skip

Then when it tells you what you are looking for you can exit with:
git bisect reset

BORING!


Right lets automate it! You can run any command that you can run on the shell and have it return the state to bisect.

Exit codes
we just exit the script with the following numbers to tell bisect what state the commit is in

  • GOOD - 0
  • BAD - 1
  • SKIP - 125

I'll make a little noddy function to test
module.exports = function add (a, b) {
  return a + b
}

I then add a few commits and break it on the way,

for this example I put my testing script outside the main git repo so that the checkouts won't have a problem.

try {
  const add = require('../bisect_script/')

  const result = add(2, 2)

  if (result == 4) {
    process.exit(0)
  } else {
    process.exit(1)
  }
} catch (err) {
  process.exit(125)
}

Then we can run the script against bisect with
git bisect start HEAD HEAD~5
git bisect run node ../bisect_test_Script/test.js

OUTPUT

cce8f28154071789a33a8b101cd11dc6bae2cf33 is the first bad commit
commit cce8f28154071789a33a8b101cd11dc6bae2cf33
Author: Robert Gill <envman@gmail.com>
Date:   Sun Jul 8 16:48:30 2018 +0100

    more logging: broke it

:100644 100644 e1dbfd4a103f424f065510204f9ae5ff80db1625 5c87270f0517cf407c4d486796899be2d87bc124 M index.js
bisect run success
Just make sure you do git bisect reset after to get back to the starting point.

Code Example (2 repos subject and test script)
https://github.com/envman/bisect_me
https://github.com/envman/bisect_test_script

You may need to update paths in bisect run and the test script to make it work depending on how/where you clone.

To Git! From TFS!

So I found this blog from a few years ago I never posted it and rolled it in glitter, maybe it's useful... also I'm probably going to write some more posts on git soon, so why not give some history...

This is my attempt to help out people that are thinking about migrating to git from TFS, I believe git has many advantages over TFS but have seen many people struggle and complain? when using it for the first couple of weeks. To put in context I have used git for 6+ years but was helping the rest of the company I am working for move over to git.

Git for TFS Users

If you just use your source control for checking in and getting latest git is probably going to add some confusion to your workflow. Visual Studio tries to hide the extra steps that are going on under the covers, which is fine when things are going good but will probably lead to you making mistakes because you don't fully understand what is happening when you are performing source control operations.

You're probably going to hate git

Git is not perfect, its complicated and has a horrible learning curve. Here's a site that might help. You might think that you can just switch to git and off you go (how difficult can it be eh?). Try it... go on...

Basic Cycle Differences

TFS
  • Get Latest
  • Check in
Git
  • Fetch
  • Merge
  • commit
  • push

DVCS

Git is a distributed version control system, so it does not necessarily have to have a central repository but i can handle this setup and is probably most used in this way. But it does allow for connecting to multiple "remotes", this means you could directly push between users or setup more complicated systems.

Source Control Usage

When you first start using source control the purpose is quite simple, let me share my code with the people I am working with and track the changes in a way that I can understand what happened when two people are making changes in the same place. So you need a few basic operations:
  • Push my code in
  • Get other peoples code
  • Merge when bad times happen =[
Nowdays I find myself wanting quite alot more than I used to
  • Quick and easy branching
  • Ability to merge locally?
  • Private areas for subsets of team to work on same code
  • Have my source control help me to find where defects where introduced
  • Ways to track previous versions so that they can be patched and managed
When comparing git to TFS it seems like I can do all of this in TFS, it just doesn't seem to be the way it wants me to use it, it's hard to explain but creating branches seems like a light weight trivial task with git, I create them all the time and throw them away, with TFS they seem big and clunky...

Source Control as a Tool

There is so much more that you can do with source control than just check in and checkout files.
  • Marking previous versions so that you can bugfix
  • Working with subsets of your team on features without affecting the whole team
  • Managing check ins via code reviews
  • Search through history to find out where errors came from

Tips for changing to git

  • Make an effort to learn the differences and what is going on under the covers
  • Have someone on standby to fix things when they go wrong
  • Practice with a test repository before moving over

Checkout

When you checkout in git the contents of the working directory are changed to whatever commit you are checking out. You maybe are checking out the v0.1 branch. Once this command is run the contents of the repository will be whatever commit the v0.1 branch is pointing to.

Branching

Branching is where git really gets in to its own, its the flexibility and ease of its branching that allows for all the cool workflows and ... that really make git so powerful.

Branching in git is different from TFS, in TFS you branch a folder and essentially have two versions of that folder that have similar contents. In git you branch the working directory, so you can only see one branch at a time (unless you download the repo twice).


Tools

Visual Studio - now has pretty decent git support 
Source Tree
Git Kraken
Command Line - my personal preference, so much tooling now has good cli interface and requires me to hit the terminal, docker, k8, git, node

References / Further Reading

http://pcottle.github.io/learnGitBranching/
https://try.github.io/levels/1/challenges/2
http://git-scm.com/book/en/v2
http://roadtoalm.com/2013/07/19/a-starters-guide-to-git-for-tfs-gitwits/
https://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/DEV-B330#fbid=
http://stevebennett.me/2012/02/24/10-things-i-hate-about-git/
http://think-like-a-git.net/

Friday, 6 July 2018

Git Abuse: Making a git repository without git

notes

I'm doing this on OSX terminal, so will probably work on OSX/Linux, less likely on command prompt. Use CMDER to be happy...

First we create an empty folder to house our working directory
mkdir gitdemo
cd gitdemo
Then create the .git folder that stores our copy of the repository
mkdir .git
cd .git

Now we start creating some git files, the HEAD file contains a string that says what the HEAD currently points to, HEAD is a pointer to the currently checked out location.
echo "ref: refs/heads/master" > HEAD

Then we create the objects folder
mkdir objects

Then we create the refs folder with the heads folder inside of it
mkdir refs
cd refs
mkdir heads

You can now use this as a working git repository!
Make sure you change back to the gitdemo directory
cd ../..
echo "console.log('hello')" > index.js
git add -A
git commit -m "initial commit"

If you've done everything correctly this should work!

Now if you look inside of the .git folder you can see that git has started adding more things to the objects folder, as well it has created ./.git/refs/heads/master

cat ./.git/refs/heads/master

This should output a commit hash, so we see that this basically says master is on this commit.

I wonder if we can create a branch by just copying this file...
cat ./.git/refs/heads/master ./.git/refs/heads/mybranch
git branch

Now displays
* master
  mybranch

But then could we check this out by changing the HEAD file, I mean it won't update the working directory but as they are both pointing at the same commit this should be fine?

echo "ref: refs/heads/mybranch" > HEAD
git branch

Now displays
  master
* mybranch

Hopefully this starts to give you an understanding of how gits refs/branches and HEAD work on disk.

Thursday, 5 July 2018

Working with Git Submodules

Git submodules enable you to have repositories inside of each other, this can be a useful mechanism to share code between projects.

Adding a submodule to a project
git submodule init
git submodule add [url] (you can use git submodule init [url] [foldername] to specify folder)

Where [url] is the location of the git repository.

git add -A
git commit -m "Add submodules"
(then push if you want to share!)

This will add a reference to a specific commit to the project.

Downloading submodules in a repository that already has them setup
Clone the repository as normal
git clone [url]

Then init/update the submodules
git submodule init
git submodule update

If you haven't already cloned you can do
git clone --recursive-submodules [url]

updating the submodule
cd into the modules folder
cd mysubmodule

Then use normal git operations, i.e. pull
git pull

then cd back to the main repository and commit the update
git add -A
git commit -m "updated submodule"

Reset submodule to the commit stored in the parent
git submodule update

This will checkout the specific commit that is stored in the parent repository.

Changes in the submodule
When in the submodule folder you can make changes to the modules repository using normal git commands. Just make sure you push then add/commit in the parent repository so that everyone else gets the changes when they do submodule update.

Automatically updating submodules on git pull
You can git to automatically update submodules by adding the following setting to gits config (you could also just set this per repository)

git config submodule.recurse true

Tuesday, 3 July 2018

Javascript packages in JSCore on iOS

unfortunately most javascript packages are either designed to work with a browser or in node.js using the CommonJS module loader. When working in JavascriptCore you aren't really using either of these.

Loading the Scripts
Download the scripts from NPM or via a CDN/Github. Ideally you want it in a single file as this is going to be much easier for you to load.

Browser packages
for a browser package it will normally check to see if it is running on a browser by seeing if the window object exists, and will often add its output to the window object. Duplicating this can be pretty simple, just evaluate a script that says var window = {} before running the packages script.

CommonJS/Node packages
Node packages use the CommonJS module pattern, they often check to see if they are running in a platform that supports this by checking for the existence of module and module.exports objects. You should be able to replicate this by adding var module = {}; var module.exports = exports = {};

You will run into further problems trying to import multiple files that use the commonJS module system, as this system uses a function called require() to load packages from disk.

CommonJS in Javascript Core
In theory you could implement a version of common JS within JSCore by adding a require method that loads and caches the contents of separate files.

Monday, 2 July 2018

BlockChain

Blockchain is the technology that backs bitcoin and other crypto currencies allowing for a peer to peer financial system. ok so it works for money but what else would you like to be able to make a peer 2 peer system for? blockchain technology can be used and adapted to help solve many problems.

Problem

In a centralised system the server is the trusted third party, so when you send money to another person the server stores the record of how much money you have. We trust that server to let you know how much you have and make sure others don't abuse the system. So we don't need to trust every one that uses the system just the server.

In a peer to peer system we know that any node we connect to could be untrustworthy, but somehow we have to validate what is true or not within a system where multiple nodes could be trying to abuse the system.

Solution

The solution has several parts

  • Group updates together into blocks, with each block having a single parent.
  • Make every node validate every update (block) based on the systems rules.
  • Make it random (ish) which node creates the next block.
  • Make it difficult to produce a block so that people cannot rewrite history.

Block
Each set of updates or transactions is grouped together into a block, with each block referencing the block that came before it, This way with the latest block you can trace back the history of any updates.

Making it difficult
To make it difficult to create a block we introduce a problem that will need to be solved before a block can be produced, we make the problem hard to solve and easy to verify, like opening a combination lock without knowing the key, spinning each dial to all possible positions until the lock opens takes much time, but is easy for someone else to confirm that you solved it correctly. To do this we take the data of the block and generate a SHA-1 Hash of it, we then see if it matches some criteria, I.E. it starts with 0000, if it doesn't we increment a number inside of the block and try again, This is essentially what bitcoin miners are doing, solving millions hash calculations.

Making it Random (ish)
Because of the nature of hash calculations some people's potential blocks will solve much faster than other peoples, this means that even if you control much of the processing power of the network, you should still get beat some times.

Handling network Lag
Sometimes different parts of the network can create different blocks at the same time, this can cause there to be 2 valid but differing histories, we consolidate these histories by allowing nodes creating new blocks to work on creating new blocks on top of the block they saw first, after time it is unlikely that the differing blocks will have more blocks piled on at exactly the same time. So we can solve the difference by saying the truth is the block with the longest history, or if they histories are the same length assume it to be the one you saw first temporarily.

Basic Networking
Each nodes connects to other nodes via TCP, and broadcasts anything it would like to add to the network (Completed Blocks, transactions), it also validates and re broadcasts any data that it receives. Thus most nodes will know about a transaction before it is validated. Transactions are often considered valid after a certain number of conformations (block length after transaction added). Because the longer the chain after it the more unlikely a duplicate block will overtake it as the leader.