Coding comments edit

It can be tricky to know what you can and can’t use when looking at free libraries. The following is a quick rule of thumb for Open Source Licenses.

Good

Bad

Some licenses are explicitly not OK to use. For example, none of the copyleft licenses can be used in a closed source project. The following list is not exhaustive. Just because a license is not on the list does not automatically mean that it can be used.

Dual Licenses

It is possible for a project to have more than one license specified. Unless specified otherwise in their licensing, all clauses from all licenses may apply. This means that, to be safe, each license to be on the compatible with the consuming project.

Other Licenses

Any other license must be evaluated on a case by case basis.

More Information

The Open Source Initiative has lots of useful information about OSS licensing. Choose A License does a great job of breaking down the most common licenses comparing the differences between them.

coding comments edit

These are the general rules and guidelines I use when developing. As with most rules, there are exceptions to all of these.

Code Quality

  1. Prefer composition over inheritance
  2. Small classes and small methods. Anything over 30 lines for a method is a smell, over 100 is a NO
  3. Pay attention to code readability. It’s been pointed out before, but other developers will have to read your code. And “other developers” includes you in 3 months. You are writing for them, not for the compiler. If they can’t understand what’s going on, you haven’t done your job.
  4. Comments get out of date very quickly so only add them in cases where they bring true value, as opposed to making them a supplement for code that has poor readability. This typically means that you shouldn’t be commenting on what your code does. Whoever is reading it should already know what it does. Comments should elucidate why your code is doing what it does. You may have had to write the code in a non-obvious way to avoid a bug. Explain that.

C# Coding Style

For most of my career I’ve been a C# developer. So my more specific rules apply to that. Despite that, many of them can be generalized to other domains. These rules were adapted and inspired from the corefx project, the general rule is “use Visual Studio defaults”.

For non code files (XML, JSON, etc.) my best guidance is consistency. When editing files, keep new code and changes consistent with the style in the files. For new files, it should conform to the style for that component.

  1. Use Allman style braces, where each brace begins on a new line. A single line statement block can go without braces but the block must be properly indented on its own line and it must not be nested in other statement blocks that use braces (See issue #381 for examples – read the resolution, not just the first comment).
  2. Use four spaces of indentation. No tabs. Never tabs.
  3. Use _camelCase for internal and private fields and use readonly wherever possible. Prefix instance fields with _. When used on static fields, readonly should come after static (i.e. static readonly not readonly static).
  4. Avoid this. unless absolutely necessary.
  5. Always specify the visibility, even if it’s the default (i.e. private string _foo not string _foo). Visibility should be the first modifier (i.e. public abstract not abstract public).
  6. Namespace imports should be specified at the top of the file, outside of namespace declarations and should be sorted alphabetically.
  7. Avoid more than one empty line at any time. For example, do not have two blank lines between members of a type.
  8. Avoid spurious free spaces. For example avoid if (someVar == 0)..., where the dots mark the spurious free spaces. Consider enabling “View White Space (Ctrl+E, S)” if using Visual Studio, to aid detection.
  9. Use language keywords instead of BCL types (i.e. int, string, float instead of Int32, String, Single, etc) for both type references as well as method calls (i.e. int.Parse instead of Int32.Parse). See issue #391 for examples.
  10. Use ALL_CAPS to name all constant local variables and fields. The only exception is for interop code where the constant value should exactly match the name and value of the code you are calling via interop.
  11. Use nameof(...) instead of "..." whenever possible and relevant.
  12. Fields should be specified at the top within type declarations.
  13. When including non-ASCII characters in the source code use Unicode escape sequences (\uXXXX) instead of literal characters. Literal non-ASCII characters occasionally get garbled by a tool or editor.
  14. One class per file. When we have a generic and non-generic definition of a simple class, they can be in defined in the same file.
  15. Member fields must be private (who creates public fields anyway?)
  16. CamelCasing of all variable and method names; methods and properties start with a capital
  17. Avoid #regions
    • Specifically included
      • Regions around common sections of code. e.g. regions around all fields or properties
    • Exceptions
      • Regions around particularly long constants or literals
      • Regions around auto-generated code
  18. Only capitalize the first letter in an abbreviation/initialization when using it in a name. For example:
    • DbPool() ✔️
    • DBPool()
  19. Partial classes: you need to have a very good reason to use a partial class. Tool generated code is one of them.
  20. Avoid multiple returns from a single method unless it is very clear.
  21. Avoid multiple escape routes from a loop, i.e., excessive use of break or continue
  22. Avoid while(true)
  23. Avoid structuring code so that it requires casting; consider generics instead. For example, you have a method that calls another method which returns an instance of an interface. If you need to cast that returned value to a specific class, then you have made a design mistake. Example below
  24. Do not use ApplicationException
  25. Implement the common constructors when making a user-defined excption
  26. Do not use goto

Example of braces on single line statement blocks

✔️ GOOD

if (isFriday) Dance();

// OR

if (isFriday)
{
    Dance();
}  

NEVER THIS

if (isFriday)
    Dance();

Order of items in a class

Note: Codemaid will do this automatically using CTRL + M then space

In a given class sort by:

  • First the type of item
    • Constants
    • Fields
    • Constructors
    • Events
    • Properties
    • Methods
  • Then by accessibility
    • public
    • internal
    • protected Internal
    • protected
    • private
  • Then statics vs instance
    • static
    • instance
  • Then alphabeticly

Bad Casting

This first version forces the caller to cast

public interface ISomeInterface { }

public class SpecificInstance : ISomeInterface
{
    public string Name {get; set;}
}

public interface IReturnAnInterface
{
    ISomeInterface GetInterface();
}

public class ReturnASpecifcInstance : IReturnAnInterface
{
    public ISomeInterface GetInterface()
    {
        return new SpecificInstance() { Name = "MyName" };
    }
}

public void BadCasting(IReturnAnInterface factory)
{
    ISomeInterface instance = factory.GetInterface();
    OtherMethod(((SpecificInstance) instance).Name);
}

✔️ Using generics allows us to avoid the cast

public interface ISomeInterface { }

public class SpecificInstance : ISomeInterface
{
    public string Name {get; set;}
}

public interface IReturnAnInterface<T> where T:ISomeInterface
{
    T GetInterface();
}

public class ReturnASpecifcInstance : IReturnAnInterface<SpecificInstance>
{
    public SpecificInstance GetInterface()
    {
        return new SpecificInstance() { Name = "MyName" };
    }
}

public void NoNeedForCast(IReturnAnInterface<SpecificInstance> factory)
{
    SpecificInstance instance = factory.GetInterface();
    OtherMethod(instance.Name);
}

Example File:

` SampleClass.cs`

using MySampleCode.SubNamespace;
using System.Linq;
using ZSoft.ThirdPartyNamespace;

namespace MySampleCode
{
    public class SampleClass
    {
        private const int DEFAULT_AGE = 0;

        private static readonly string _someStaticValue;

        protected internal int _size;
        protected double _length;
        private readonly string _vision;
        private string _flavor;

        public SampleClass(
            ITrialUserLicenseCreator trialUserLicenseCreator,
            IUserIdentityProvider userIdentityProvider,
            ILoggedInUserInformationFetcher identityFetcher)
        {
            if (trialUserLicenseCreator == null) throw new ArgumentNullException(nameof(trialUserLicenseCreator));
            // ...
        }

        private SampleClass(string vision, IUserIdentityProvider userIdentityProvider)
        {
            _vision = vision;
        }

        public event EventHandler OnFlavorChanged;

        public string Name { get; set; }

        public void Method()
        {
            // ...
        }

        private int GetIntValue(string value)
        {
            if (string.IsNullOrWhiteSpace(value)) return -1;

            if (value.All(c => char.IsDigit(c))
            {
                return int.Parse(value);
            }
            else 
            {
                return 0;
            }
        }
    }
}

Most of this (all of it) was stolen from Ron’s response to me asking a question on slack.

Took me about a month of raging when I first switched to OSX. These tips might help:

Shortcuts

Keyboard

Keys Effect
⌘ + L Address bar
⌘ + Q Close app
⌘ + Space Spotlight
⌘ + ⌥ + Space Finder
Ctrl + ↑ Mission Control
⌘ + ↑ / ⌘ + ↓ Move up and down the tree. Doing it on a file opens it.
F11 Show desktop
F12 Show dashboard
Ctrl + F3 Focus Dock
Ctrl + F4 Alt-Tab
^ + ⌘ + 3 Save screenshot to file
Ctrl + ^ + ⌘ + 3 Copy screenshot to clipboard
^ + ⌘ + 4 Save screen region to file
Ctrl + ^ + ⌘ + 4 Copy screen region to clipboard
^ + ⌘ + / Show Help Menu
⌘ + ⌥ + → Next tab (chrome)
⌘ + ⌥ + ← Previous tab (chrome)

Magnet

Keys Effect
^⌥← Left
^⌥→ Right
^⌥→ Up
^⌥↓ Down
^⌥U Top Left
^⌥I Top Right
^⌥J Bottom left
^⌥K Bottom Right
^⌥D Left Third
^⌥E Left Two Thirds
^⌥F Center Third
^⌥T Right Two Thirds
^⌥G Right Third
^⌥↵ Right Third
^⌥C Center

Trackpad Gestures

Gesture Effect
Scroll left or right with two fingers Swipe between pages
Swipe left or right with 3 fingers Switch desktop
Swipe left from edge Notificatin Center
Swipe up with three fingers Mission Control
Pinch with all the fingers Launchpad
Spread out thumb and three fingers Show Desktop

Finder keyboard

They actually feel more rational to me than Explorer now tbh.

  • Cmd+up/down to move up and down the tree. Doing it on a file opens it. Vs
  • Explorer, you have to switch to Enter to open a file. Hitting enter on a
  • file (or most labels really) initiates a rename vs F2

In general:

  • Cmd+Space is your friend
  • As Kevin mentioned, Cmd instead of Ctrl. I actually prefer this now since I can use my thumbs for Cmd instead of my pinkies for Ctrl (my thumbs are usually out of play for keyboard shortcuts anyway). Think Cmd+A vs Ctrl+A
  • Cut/Paste flow is different. It’s more like Copy/Move and Move is considered a modification to Paste, so copy as usual (CMD+C), then modify Paste into a Move with Option (Option + CMD +V)
  • Option modifies all sorts of things, and they aren’t well documented. Try option clicking everything I guess. E.g. after right clicking on a folder in Finder to show the context menu, you can hold down Option to show additional command variations
  • You can drag files from anywhere into an Open File dialog and the dialog will jump to that path with that file selected. Versus Windows, last time I used it, doing that will just freak it out.
  • If you hate excessive clicking like me (and it sounds like @brewdente also), turn on triple finger dragging, which lets you just do a 3 finger touch to drag windows around. Otherwise, you have to do a full click, hold it down, and drag. It’s oddly hidden in Accessibility now.
  • You can change touch to be equivalent to click, so it’s more akin to a smart phone (I hate clicking)
  • Turn on the speaker and bluetooth icons. All those status icons are hidden by default. You can turn them all on in System Preferences. This lets you quickly switch inputs and outputs.
  • If you Option click the Notification icon in the top right (looks like a modified hamburger icon), it’ll snooze your notifications. Great for when you’re presenting off your mac and you don’t want random calendar invites appearing
  • There are a lot of 3rd party windows managers if the OS ones aren’t sufficient, like Magnet
  • Install this if you want a soothing screen saver: https://github.com/JohnCoates/Aerial

Windows management

  • Full screen is weird on macOs and defaults to launching an addtl desktop for it. If you’re into multiple desktops, I guess that’s fine, but I never used them under either OS.
  • If you DO like multidesktops, click and drag an app to the top and beyond (like you’re trying to go off screen with it). It’ll prompt you to move the app into a different desktop.
  • Not sure if this was ever added to Windows, but same thing, if you move your mouse to the edge of an app, you get the resize icon. but if you double click instead, it’ll go full screen in that direction only.
  • Hold down the green full screen button on an app to trigger side by side mode. You can also use the drag up technique I mentioned above to trigger the same effect on a different desktop if there’s already a full screen app on it
  • Triple finger swipe down on the touch pad will show all open windows for the current app only
  • Closing all windows is not equivalent to exiting the app. Not sure if MS ever changed that for Windows, but it drove me crazy whenever I accidentally closed my only browser window and it defaulted to exiting out. Cmd+Q to actually exit an app.

Hope that helps.

To solve the 4x4 cube you need to reduce it to a 3x3 cube. You do this by solving the 2x2 centers on each face first. Then pair up the edges in 2x1 strips so you can treat them like a single edge on the 3x3. After that the entire thing feels like solving the 3x3. The one caveat is that you may have parity errors going into the “yellow cross” stage.

Below are the additional algorithms needed for the edges and parity.

Edges

To solve the last two edges, make sure they are both facing you and are lined up (not diagonal from their pair):

Dd  R   F'  U
R'  F   Dd' 

Parity

There are tons of parity issues that you can encounter. And then there are tons of sequences to correct each one. I’m just listing the ones I use to fix the scenarios that I encounter. SpeedCubing.com has an exhaustive list.

Edge Parity

This algorithm will flip the top two edge pieces on the front face without moving any other pieces

r'  U2  l   F2
l'  F2  r2  U2
r   U2  r'  U2
F2  r2  F2 

Corner Parity

This sequence will swap the two front most top corners.

F2  R2  B'  D'
B   R2  F'  U
Ff2 F   L2  f2
Ll2 f2  l2  U'

A note on notation

Most of the notation is the same as the 3x3 cube notation, for example F means rotate the front face clockwise. F' means rotate the front face counter-clockwise. Some additions just for the 4x4 are:

  • l (lower case L): rotate the column second from the left clockwise
  • r: rotate the column second from the right clockwise
  • Dd: the equivalent of doing a D and then a d. It basically means rotate the entire bottom half.

Some brief notes on solving a traditional 3x3 Rubik’s cube. These instructions assume that you are starting by solving the white face first.

  1. Solve for the white cross
  2. Solve for the white corners and corresponding edge at the same time
  3. Solve for the yellow cross (three possible starting points)
  4. Hook
  5. Bar
  6. Dot (use either the hook or bar)
  7. Put yellow edges in correct spots
  8. Put yellow corners in the correct location
  9. Put yellow corners in the correct orientation

Hook

Start with yellow hook in the top left corner.

Starting top layout:

|   | Y |   |
| Y | Y |   |
|   |   |   |

Ending top layout:

|   | Y |   |
| Y | Y | Y |
|   | Y |   |

F U R U' R' F'

Bar

Start with yellow bar going horizontal

Starting top layout:

|   |   |   |
| Y | Y | Y |
|   |   |   |

Ending top layout:

|   | Y |   |
| Y | Y | Y |
|   | Y |   |

F R U R' U' F'

Edges

This sequence swaps the front edge with the left edge on the top of the cube. So start with the edges you want to preserve on the right and back. It may be the case that there are no two edges that are correctly adjacent. In that case, you’ll just have to do this bit twice.

Starting top layout:

|   | B |   |
| O |   | G |
|   | R |   |

Ending top layout:

|   | O |   |
| B |   | G |
|   | R |   |

R U R' U R U2 R' U

Corner Location

This sequence rotates the corners. If the corners were numbered clockwise starting in the top left as 1, 2, 3, 4, then after this sequence the would be : 4, 1, 3, 2

Starting top layout:

| 1 |   | 2 |
|   |   |   |
| 4 |   | 3 |

Ending top layout:

| 4 |   | 1 |
|   |   |   |
| 2 |   | 3 |

U R U' L' U R' U' L

Corner Orientation

This sequence rotates the corner in the front right hand corner of the top. Orient the cube so that the corner you want to change is there. Run this algorithm one or two times. Once it’s complete, rotate just the top so that the next corner you want to fix is in the front right hand corner of the top. Repeat until all the corners are correct.

Note that the algorithm repeats itself, so it’s really a short one to learn.

R' D' R D R' D' R D

C#, interviews comments edit

When interviewing tech candidates, I don’t like prescribe a language or methodology. That being said, I’ve found that it can be helpful to provide a cheatsheet for C# since that’s how I tend to phrase the questions. This code tries to provide the basics of how to define and use classes.

public interface IProduct
{
    string Name { get; set; }
    string Id { get; set; }
}

public class Product : IProduct
{
    public Product(string name, string id)
    {
        Name = name;
        Id = id;
        Creation = DateTime.Now;
    }

    public string Name { get; set; }
    public string Id { get; set; }

    public DateTime Creation { get; set; }
}

public interface IProductLoader
{
    IProduct[] Load();
}

public class ProductLoader : IProductLoader
{
    public IProduct[] Load()
    {
        Product[] products = new Product[]
        {
            new Product("DeLorean", "B2TF88-1955"),
            new Product("Beans, Magic", "GNT-42"),
        };

        return products;
    }
}

public class Main
{
    public void Start()
    {
        IProductLoader loader = new ProductLoader();
        IProduct[] products = loader.Load();
        foreach (var product in products)
        {
            Sell(product);
        }
    }

    private void Sell(IProduct product)
    {
        Console.WriteLine($"Selling {product.Name}");
    }
}

management comments edit

I hold one on one meetings bi-weekly with my direct reports for two reasons. First, I want to get feedback from them about how they are doing. Do they need help? Do they need more work? Different work? Is there something bothering them that isn’t going to come up without prodding?

Secondly, I use the to discuss career growth and progression. What are the options (both in the current company and in other companies) for their long term career? What do they want for their long term plans? Given that, what should they be doing now to work towards that?

This is their time to voice their concerns and ask questions.

Format of the One on One

The following is the general outline I follow when doing a one on one meeting with direct report. The exact order doesn’t matter (although I do stick to it because it’s just easier for me to remember) but I try to hit each of these beats each time. In general the conversations last about an hour.

  1. What’s up?
  2. Review goals
  3. Project status
  4. Meeting follow ups
  5. Request for feedback

What’s up?

Before getting to far in the conversation, check if there’s anything that the report would like to talk about. More often than not, there isn’t, but since the point of this meeting is to check in with them, then it’s a good idea to let them lead off.

For instance, at this point we may wind up discussing specific project statuses or blockers.

Review goals

Every other meeting I like to check in on goals. I’ve found checking too often becomes monotonous not checking enough is worse. So I make sure to ask every time, even if we wind up not talking about it half the time. I’m up front with my reports about this so they tend to either remind me if I forget, or tell me “Not this week” if we’d already talked about it recently.

This implies that we’ve already worked through and have written down goals for the upcoming year. If we don’t then it becomes a priority to create a list of goals. This will probably take several weeks of focus in the one on ones.

I leave it up to each person to track their goals however works for them. Some take notes in excel, some in word. Some don’t take notes.

When discussing goals I’m looking to see if progress is being made, and if not why not. Does the goal no longer make sense? Was it too vague to begin with? Is there nothing to do toward it until later in the project cycle? I also try to check if there are any other new goals that we should try to incorporate into our conversation.

Project status

Discuss the overall project that the team is working on, make sure that they know how their work fits in. At this point they can ask questions about any aspect of the project, e.g., timeline, design, resourcing.

I tend to ask how they feel about the general health of the project, if they think it is on schedule.

Meeting follow ups

Since we have so few team meetings I like to review each one to see:

  1. Are they getting something out of the meeting?
  2. Did they have any follow up questions from the meeting?
  3. Did they feel like they had a voice in the meeting?
  4. Is the intent of the meeting clear? Is it worthwhile to be spending this much time for that reason?
  5. Is the format of the meeting helping us get the type of information/feedback we want?

Request for feedback

Ask if there’s anyway I can be doing a better job hearing them or helping them. I tend not to get an answer to this, but when I do it’s really useful and makes it worth asking each time.

Recipes, Desserts comments edit
Cook Time Oven Temp
~30 min 350°F

Ingredients


  • 1/3 cup (or 1 oz) Dutch-processed cocoa powder
  • 2 oz unsweetened chocolate
  • 6 oz bittersweet chocolate cut into 1/2 inch pieces
  • 1/2 cup + 2 tsp boiling water
  • 1/2 cup + 2 tsp vegetable oil
  • 4 tbsp unsalted butter
  • 2 large whole eggs + 2 egg yolks
  • 2 tsp vanilla
  • 2 1/2 cup sugar
  • 1 3/4 cups all-purpose flour
  • 3/4 tsp salt

Oven Prep


  1. Put oven rack to lowest position
  2. Preheat oven to 350 degrees F
  3. Put a foil sling in a 13x9 inch pan
  4. Spray with nonstick spray

Mix it


  1. Whisk cocoa and boiling water together in a large bowl until smooth
  2. Add unsweetened chocolate and whisk until melted
  3. Whisk in oil and butter (may look curdled)
  4. Whisk in add all eggs and vanilla until smooth
  5. Whisk in sugar
  6. Add flour and salt, stir with rubber spatula
  7. Fold in bittersweet chocolate

Bake it


  • 30 - 35 minutes
  • Let cool in pan on wire rack for ~90 minutes
  • Remove from pan in sling and continue to cool for another hour on the wire rack

The out of the box console environment in Windows can leave a lot to be desired. It’s hard to resize, copy/paste doesn’t work out of the box, etc. ConEmu and Cmder wrap the existing cmd console (really it works with any console app) and fixes a lot of these issues. Some features (mostly stolen from the website)

  • Smooth window resizing
  • Tabs and splits (panes)
  • Easy run old DOS applications (games) in Windows 7 or 64bit OS (DosBox required)
  • Quake-style, normal, maximized and full screen window graphic modes
  • Better fonts
  • Using normal/bold/italic fonts for different parts of console simultaneously
  • Cursor: standard console (horizontal) or GUI (vertical)
  • Easily select various environments (PowerShell, cmd, admin consoles, etc)
  • Hot keys
  • Better mouse integration in the console

ConEmu and Cmder work in conjunction. ConEmu is the base application and Cmder adds additional configuration and settings. I’ve used them together for so long that I don’t really know which settings are from which program.

The rest of this post will assume you’re already using ConEmu and focus on how to set it up in a way that allows you to customize your console environment and keep it in sync across multiple computers. An added bonus of these requirements is that it makes it trivial to restore your environment when reinstalling Windows or getting a new computer.

Install Cmder and ConEmu

First up, installation. This is easy, just use chocolatey

choco install -y cmder.portable

Export Settings

Well that was easy. Next we’ll start up Cmder and export the existing settings configuration. If you haven’t used the app yet, the defaults are still worth exporting since you need a starting point.

  1. Open up Cmder from the Windows Start Menu (this will start ConEmu)
  2. Open ConEmu’s settings window by using the hotkey Win-Alt-P or by clicking the hamburger menu on the bottom right corner.
  3. Click the Export button that shows up in the bottom right. Export Settings
  4. Save the file to a folder you sync across your computers (OneDrive, Dropbox, etc). I use c:\users\joshq\OneDrive\bin\ConEmu.xml

Use Exported Settings

Now that we have our configuration in a non standard location, we want to tell ConEmu to use it.

  1. Start up ConEmu from the Windows Start Menu
  2. Right click on it in the taskbar and select Pin to taskbar
  3. Close ConEmu to verify that the pin was created
  4. Next update the shortcut
  5. Right click on the pin
  6. Right click on Console Emulator
  7. Click Properties

    Configure Pin Properties

  8. Change the target to include the -LoadCfgFile <Path To Exported Config> (using the config file we exported above)
     Files\ConEmu\ConEmu64.exe" -LoadCfgFile C:\Users\joshq\OneDrive\bin\ConEmu.xml
    
  9. Click OK
  10. Repeat this on every computer you want to use ConEmu

Now no matter what type of configuration change you make to ConEmu, your settings will follow you across all computers and to any new ones.

Configuring ConEmu

Speaking of configurations, what’s worth tweaking from the default install?

Tweak tab settings under Main/Tab Bar. If you’d prefer that ctrl-tabbing cycles between all tabs instead of just the most recent two, deselect Recent mode on the top right hand corner of the page. You can also change the what the tabs say by default by changing the Console: setting. I use ` %m->m %n %f. It indicates the current tab with an arrow (->`), and shows the currently running command and folder.

Under Startup, you can tell ConEmu remember your open tabs between sessions by selecting Auto save/restore opened tabs.

With Freatures\Transparency, you can configure different transparencies for your console when it is active and inactive. This can get pretty annoying if you make it to transparent, but it is a nice feature if used sparingly.

And most importantly, under Startup\Tasks you can configure which consoles are available when you press Ctrl-T. For me the minimum are cmd, an admin cmd, and a PowerShell prompt, but you can configure PuTTY, Ubuntu prompt using WSL, Visual Studio’s developer command prompt, or really any program that runs under a command prompt.

Tasks

Configuring cmd

The standard cmd.exe can be started with the /k argument to specify a .bat script to run at startup. This script can let you further customize your console environment. You can use it to set environment variables or aliases. It’s similar to a .bashrc in the Linux world.

To take advantage of this, edit the cmd task and set the command to run to be something like:

cmd /k %HOMEPATH%\OneDrive\bin\cmdinit.bat -new_console

We’re saving the script in the same OneDrive directory as our ConEmu configuration file. This way both will be sunk and the console environment will follow us from computer to computer.

This sample script does a few things:

  1. Adds a couple of additional folders to either the beginning or end of the current PATH
  2. Uses DOSKEY to configure some quick shortcuts to go from the command line to the File Explorer
  3. Uses DOSKEY to configure some aliases for frequent git commands. For instance, all we have to do now is type s to show the git status of the current directory, or co master to switch to the master branch.
  4. Uses DOSKEY to add a quick way to edit the configuration script (aliases) and another to reload the script if any changes have been made (refresh)
  5. Print out the current directory
@ECHO OFF
REM Console Startup Configuration
REM ******************************************

REM Setup PATH
REM ******************************************
SET PATH=%HomeDrive%%HomePath%\OneDrive\bin;%PATH%
SET PATH=C:\Program Files\Git\cmd\;%PATH%
SET PATH=%PATH%;C:\tools\sysinternals

REM Open the current directory in File Explorer
REM ******************************************
DOSKEY   ex=explorer $*
DOSKEY  ex.=explorer .

REM Git
REM ******************************************
DOSKEY push=git push
DOSKEY pull=git pull
DOSKEY   co=git checkout $*
DOSKEY    s=git status

REM Make it easy to edit this file
REM ******************************************
DOSKEY aliases=gvim %HomePath%\OneDrive\bin\cmdinit.bat ^& echo Don't forget to open run `refresh` to make sure these take effect
DOSKEY refresh=call %HomePath%\OneDrive\bin\cmdinit.bat

REM Print out current path when opening a new console
REM ******************************************
ECHO.
CD

There’s a lot more that can be done to with scripts like this to configure your environment. You can use the above script as a starting point and add anything you think of as you’re plugging away by running the aliases command. Any changes you make will automatically be saved and synced.

comments edit

layout: post disqus_identifier: #32 comments: true categories:

  • Visual Studio
  • VS
  • Command Line

Despite being a developer that uses Windows, I spend a lot of time managing my code on the command line. As such I want to open up my code in Visual Studio from the command line. Typically I already know the name of the sln file, but if I don’t I can do a quick ls *.sln to find it and then type it in.

I’m lazy and that requires me to not only type more, but to also remember things. I’d much rather be able to cd to my project directory and then just type in the same thing no matter where I am and have it open up what I want. My first pass at automating this assumed that there was a single sln file in my current directory, figured out what it was and then opened it.

For the most part that works, but there are a couple of projects that have multiple sln files and/or sln files that don’t live in the root of the folder structure. In my case, there were few enough of these edge cases so I could just code around them.

Below is the batch file that I use. Each special case gets their own if/set.

@ECHO OFF
REM ***************************************************************************
REM SLN
REM ***************************************************************************
REM Find and open the prefered sln file If a prefered file can't be found, just
REM open the first one you see
REM ***************************************************************************

SET SLN=""

REM First off see if there is a fallback sln file to open
FOR /F %%i in ('dir /B/s *.sln') do (
  SET SLN=%%i
)

REM Now look if there is a preferred sln that we want to grab
IF  EXIST SecondSolutionInAFolder.sln (
  SET SLN=SecondSolutionInAFolder.sln
) 

IF  EXIST .\ConsoleApps\FunWithSpikes\FunWithSpikes.sln ( 
  SET SLN=.\ConsoleApps\FunWithSpikes\FunWithSpikes.sln
)

IF NOT %SLN%=="" (
  ECHO Starting [93m%SLN%[0m 
  START %SLN%
  GOTO:EOF
)

ECHO [91mCould not find a solution file to open.  [0m
ECHO Are you sure you are in the right directory?  [91m %CD% [0m

Installation and Usage

  1. Copy the script into a file named sln.bat somewhere in your path
  2. From the command line go to the root directory for your project
  3. Run the sln command
  4. If the wrong sln file is opened, edit your sln.bat and add another if/set
> cd c:\code\MySuperAwesomeProject
> sln
Starting .\MySuperAwesomeProject.sln

OSS, Licenses comments edit

What open source projects are OK to use in a comercially distributed product?

Good

Bad

Some licenses are explicitly not OK to use. For example, the copyleft licenses cannot be used in a closed source project. The following list is not exhaustive. Just because a license is not on the list does not automatically mean that it safe to use.

Dual Licenses

It is possible for a project to have more than one license specified. Unless specified otherwise in their licensing, all clauses from all licenses apply. This means that, to be safe, each license needs to be on the approved list.

Other Licenses

Any other license must be evaluated on a case by case basis.

More Information

The Open Source Initiative has lots of useful information about OSS licensing. Choose A License does a great job of breaking down the most common licenses comparing the differences between them.

Shakespeare comments edit

When I’m reading a Shakespear play for the first time in preperation to go to the theater I like to do a couple of things. First off, I read and reread it several times. This helps me get past the stage of just understanding what is happening (sometimes a little difficult given the language). After the second or third read through, I’m no longer just focusing on plot, but I can start to enjoy the themes and characters a lot more.

Next, I try to summarize what happens in each act and scene. In order. From memory. Again, this helps me focus on the themes, but more importantly (to me at least) it helps me remember the structure of the text when I’m in the theater. This means, I can spot the changes the production chose to make. Sure, most productions will drop all of the horse jokes because who in modern times is going to understand the joke about the old palfrey? I’m sure it went over great in the 16th century, but it doen’t really land in the 21st. But what about the other minor changes? What impact do they have on the production? Were they cut for time? Clarity? Because they conflict with the themes the production is trying to present?

Anyway, so I’m a nerd and I take too many notes when I’m ostensibly reading for pleasure. Here are my notes from my most recent reread of King Lear.

Characters

Principle players

  • Lear
    • King
  • Kent
    • Lear’s faithful servant
    • Exiled
  • Daughters
    • Goneril & Albany
    • Regan & Cornwall
    • Cordelia - The good one
  • Glouchester, Duke of
  • Edmund
    • Glouchester’s bastard
  • Edgar
    • Glouchester’s legit son
  • Fool
    • A fool

Plot Summary

Act 1

In which Lear fails to plan for his retirement.

Act 1 Scene 1

Lear decides to retire and splits up his kingdom amongst his daughters based on how much they love him. Turns out Goneril and Regan are good at professing their love. Cordelia on the other hand is more plain spoken. She gets the shaft. Kent gets exiled. France marries Cordelia.

Act 1 Scene 2

Edmund starts to make his dad think that Edgar is out to kill him for his inheritance. Bastards gotta bastard.

Act 1 Scene 3

Goneril ain’t enjoying having her dad live with her.

Act 1 Scene 4

Lear starts to chafe at living with his daughter. Kent comes back all disguised and ingratiates himself back in with Lear. Fools gotta fool.

Act 1 Scene 5

Lear heads off to his other daughter’s place with the Fool. Kent goes ahead as a messenger.

Act 2

In which Lear realizes that he should have planned for his retirement.

Act 2 Scene 1

Edmund scares Edgar into thinking that Glouchester has it out for him. Fakes a fight with Edgar and Edgar flees. Glouchester sees this as proof that Edgar was plotting against him and disowns his son. Regan and Cornwall arrive and support Glouchester in this decision.

Act 2 Scene 2

Kent arrives at Glouchester’s at the same time as Goneril’s messenger and gets sassy with him. Maybe a little too sassy since Cornwall has him put in the stocks.

Act 2 Scene 3

Edgar is evading pursuit. Decides to dress up as a crazy beggar (Tom o’ Bedlam) and go on the lam.

Act 2 Scene 4

Lear arrives to find his servant in the stocks and gets pissy about it. Regan don’t care. Goneril arrives and double teams Lear with her sister. They say as long as he is living under their roofs he has to give up his retinue of 100 knights. Whittling it down to 50, then 25, then none. Lear says F this and runs out into the storm.

Act 3

In which Lear argues with the wind, which I’m guessing is the medieval equivalent of yelling at the T.V.

Act 3 Scene 1

Kent, looking for Lear, bumps into a “Gentleman” from Lear’s retinue. Tells him that all is not lost and that France is coming with Cordelia. Scene ends with them going in separate directions in search of Lear.

Act 3 Scene 2

Lear wanders around in the storm yelling at it and wallowing in self pity. The Fool tries to cheer him up to no use.

Act 3 Scene 3

Glouchester frets over Lear being out in the storm. Tells Edmund that he’s going to help his erstwhile king. Edgar’s all like “cool. cool cool cool.” and then tells the audience that he’s totally going to rat out his dad so that Cornwall will like him.

Act 3 Scene 4

Kent finds Lear and convinces him to seek shelter. They stumble across a shack with Edmund in it who is pretending to be crazy. Glouchester finds them and invites them all back to his pad for safety.

Act 3 Scene 5

Edgar rats out his dad to Cornwall. Cornwall calls for his head.

Act 3 Scene 6

Lear has a delirious fever dream of a trial for Goneril and Regan. Imaginary Regan is imagined to run away and is then chased by imaginary dogs. Glouchester comes back and tells Kent to take Lear to Dover.

Act 3 Scene 7

Cornwall sends Goneril and Edgar back to Goneril’s castle, plucks out Glouchester’s eyes, and is stabbed. It’s just a flesh wound.

Act 4

In which reunions are made and more are hinted at.

Act 4 Scene 1

Blinded, Glouchester has been kicked out of his own castle and is brought to Edgar. Edgar agrees to take him to Dover.

Act 4 Scene 2

Goneril and Edmund arrive at Goneril’s castle. Albany (her hubby) isn’t happy about all the king-gas-lighting and eye-plucking. Goneril totes has the hots for Edmund. Cornwall dies off stage.

Act 4 Scene 3

Lear has arrived at Dover. Cordy reads a letter about how her sisters treated their dad. It made her sorrowful, but at least she’s pretty when she’s sad. Lear is to ashamed to see his daughter.

Act 4 Scene 4

A doctor tells Cordelia that there is hope for treating her dad. She sends out people in search of him.

Act 4 Scene 5

Regan talks with Goneril’s messenger. She’s concerned that Goneril might be intersted in Edmund and tries to get this information from Oswald (the messenger). She reveals that she thinks she is a better match for the new Duke of Glouchester.

Act 4 Scene 6

The cliff diving scene. Edgar (as Poor Tom) has led his father to “the edge” of the Cliffs of Dover. In fact they are nowhere near the cliffs. Edgar in the hopes of helping his father get over his suicidal depressoin encourages his father to jump. Glouchester jumps and doean’t get hurt since they are pretty much on solid ground. Edgar now pretends to be someone else and talks about how far Glouchester had fallen. Glouchester accepts this as a miracle and resolves to live his life out.

Lear stumbles in around now and starts to pontificate on morality. He’s chased off when Cordelia’s messengers find him and try to bring him back t his daughter.

Oswald next stumbles into the scene and declares his intent to kill Glouchester. Edgar, being the good son, takes issue with this and defends his father, killing Oswald. After searching the body, he finds Goneril’s note to Edgar plotting the death of Albany (Goney’s hubby).

Act 4 Scene 7

Lear has been caught and brought back to Cordy.

Act 5

In which everyone lives happilly ever after, except for the vast majority who die in the last scene.

Act 5 Scene 1

Prelude to war. Albany shows up and joins with Regan. Edmund later contimplates killing Albany.

Edgar gives Albany the letter from Goneril trying to plot his assination with Edmund.

Edmund think about which sister he wants to marry.

Act 5 Scene 2

The war has been lost. Edgar tries to reassure Glouchester who is ready to die. Which is good cuz he dies off stage between scenes.

No further, sir. A man may rot even here.

– Glouchester Line 9

Act 5 Scene 3

Edmund sends Lear and Cordelia to prison followed with orders to have them killed. Lear goes gladly. He looks forward to spending the rest of his days with Cordelia and cares not for prison.

Albany, Goneril, and Regan enter and start arguing over Edmund’s station. Goneril reveals that she’s poisoned Regan. Albany summons Edgar (no longr dressed as a commoner) who accuses Edmund of being a traitor and fights him in single combat. Edmund is mortally wounded but takes his sweet ass time to die.

Albany promises to give everything to Cordelia and Lear. Enter Lear with Cordy’s dead body. Lear dies of grief. Kent arrives to say that he’s not long for this world.

Who Dies:

  1. Glouchester (off stage)
  2. Regan (poisoned, dies off stage)
  3. Edmund (wounded in single combat, dies slowly on stage)
  4. Cordelia (hanged off stage)
  5. Lear
  6. Kent (implied to off stage soon after the completion of the play)

Resources

Notes from my March 6 - 11 2017 trip to Barcelona with Ksenia.

General Notes

We didn’t use the transit system. Either stuff was within walking distance or we took cabs. Barcelona has it’s own cab app (works like Uber), so you can hail one that way if you wish. The app is called Helo. I found the app through Google maps. Input the address in Google Maps you want to get to, and then click on “Hail a Cab” and app suggestions will pop up.

We like using our credit cards when we travel abroad (we have one that has no foreign transactions fees), and Barcelona was very credit-card friendly (unlike Germany….ugh that’s a whole other story). Also, I find that more and more places ask (when charging stuff to your CC) if you want to pay in Euros or US dollars. Definitely pay with Euros. The price difference may be small, but it starts to add up if you keep using your CC.

Eat

Ham. There are several types but what you want to eat will be the black hoof iberico. Sweat, salty, tender, melt in your mouth. Amazing.

There’s more foie here than I would have expected. We wound up eating foie and ham each and every day. It was delightful.

Tapas tend to be very regional dishes in Spain. Which means that you can only find a handful of different options wherever you go. Except Barcelona. Barcelona never had the tapas tradition, so when they started becoming a thing Barcelona just made everyone else’s and then invented some new ones. This means that if you want to try all the tapas, Barcelona is where you want to be. I enjoyed eating tapas at the bar. It’s nice to have the bartender around so you can easily and quickly order another dish. And you will be ordering another dish.

Pan con tomate or tomato bread is a common dish where they rub a mushy tomato on some crispy (sometimes purposefully stale) bread and drizzle some olive oil over it. It is delicious and you can find it everywhere. If a spot doesn’t have good tomato bread then it’s probably not worth eating anything else there.

Reservations aren’t required but can be helpful.

  • Tapas @ Catalana
    • Good not great.
  • La Pepta
    • We went to eat here twice! Ksenia still talks about the foie gras topped with white chocolate and hazelnut shavings. They do giant gintonics.
    • In can get VERY crowded in there so if you get there RIGHT at 7:30pm (when they re-open for dinner), you should be able to get a seat at the bar.
  • Walking Food Tour of Gracia
    • Gracia is a neighborhood with a unique identity and great food. This tour was one of our highlights of the trip! Highly recommend! It just so happened that on our tour it was me, Ksenia, and one other person, plus the guide. Gracia is delightful! Also, if you like getting one-of-a-kind clothing, this is the place to walk around! K got several shirts for herself and mom here. In one shop, the owner/designer had her studio right behind her, with all the materials she needed to make the shirts.
    • Stops:
      • Con Tosca - a cute cafe where we had sausage on tomato bread and a glass of cava.
      • Local market
        • I Conservas Gloria for olives
        • Fabregas for ham
        • La Trobada del Gourmet for cheese and jams
      • Oil Sal a salt and oil store where we had olive oil tasting
      • l’Anxoveta a cute bar, we had tomato bread and crouqets
      • Pastisseria Principe a Syrian pastry shop that’s been there for 30 years
      • Bodega Ca’l Pep an ancient very local bar. We had vermouth, pickled anchioves, and sausage.
      • La botigueta del Bon Menjar a small shop that sells premade food. very local
      • Pastissera Ideal another pastry shop. We had cremat - a Spanish version of creme brulee (it actually predates the French version)
  • La Pubilla
    • My favorite restaurant. I’d recommend a reservation, or just getting there when they open.
    • We ate here twice. When we came back the second time we were welcomed like old friends.
    • Between K and I, we ate like 90% of the menu between the two trips there. And we were not disappointed.
    • The waiter was gave us some great wine recommendations, they have some really local stuff there. Like 1km away local.
    • Best croquets we had
    • Homemade pate
    • The capacio was one of the best things I ate on this trip.
  • Alta Taberna Paco Meralgo
  • Tapeo del Born
    • Near the Picasso Museum. We ate here on our last night, at the bar.
    • It feels a bit more touristy but the food was still good. K liked it more than I did.
    • When we ordered our food, one of the guys behind the bar asked if we had come there before because he was impressed with our choices.
    • The Foie Gras burger was good.
  • Mercado de la Boqueria
    • Not a restaurant, but it has plenty of stalls in it where you can get all sorts of food
    • Butchers sell “meat cones” - charcuterie in a paper cone.
    • Fresh juices
    • Hot food
    • Candies
    • etc.

Drink

Gintonic has recently become a thing in Spain. According to a bartender I spoke with Hendrix put a lot of ad dollars into the area and it worked. There are dedicated gin bars with dozens if not hundereds of bottles to choose from. Josh loved these places. A lot.

While gin is the new fad, vermouth is the traditional drink. The early afternoon is called “the vermouth hour”. It’s when you’re supposed to get together with some friends and have a glass of vermouth, a few sardines, and chat.

Another classic is cava, a Spanish sparkling white wine.

  • Elephanta
    • A gintonic bar that also has a great tea list.
    • Several dozen options for gin, with useful descriptions.
    • The menus are on the back of LPs.
    • They do flights
  • Bobby’s Gin
    • Hundreds of bottles of gin
    • Very knowledgeable bartenders
    • Lots of obscure and local gins
    • No food

Do

Barcelona is the city of Gaudi.

  • Gaudi
    • Sagrada Familia
      • Definitely worth booking a ticket with a tour, the “guided experience”, as the tour guide will point out elements to you that you will have missed on your own. Tickets
      • Definitely purchase online! You can choose which time you want to go in.
      • Entrance will be on the “old” side, not the Cubist side.
      • We went in the afternoon and the lighting through the orange/red stained glass windows was AMAZING inside because the sun was setting.
      • This was by far my favorite part of Barcelona that I couldn’t eat or drink.
    • Casa Batlló
      • This house is AMAZING! Don’t miss it!
      • The audioguide is worth it. There are so many details.
      • The interior was really cool with all sorts of curved walls and doors. It felt like being in an underwater fairytale.
    • Park Guell (aka Gaudi Park)
      • So the park is free BUT if you want to go visit the section of the park with all the Gaudi stuff you have to buy a ticket and it’s timed entrances. We didn’t realize this when we went (this is a very recent thing, as the entire thing used to be free) We got there at like 3, got our ticket for 4:30, and in between that time we walked around through the rest of the park which has several layers. It is a nice walk and you have some great views. The Gaudi section will be crowded. So if you’d like, plan in advance and get tickets online for a timed entry. FYI: the entire park is up on a hill! We went to the Park after we did the food tour, because it was essentially a straight shot from the endpoint of the tour (and because stuff was closed at 2pm-ish).
    • Palau Guell
      • My least favorite of the Gaudi sites, perhaps because it was the last.
      • The roof has amazing views but is very sloped. It may not bother some people but I was terrorfied up there. Frozen and refused to move without holding on to something.
  • Free Walking Tour
    • We did three of these in Germany and one in Barcelona. Really great way for you to quickly learn the lay of the land, the history, and some great anecdotes.
  • Picasso Museum
    • I’m a huge fan and this museum is in a very nice building too! Also some good shopping in the area too!
  • La Rambla
    • Very touristy so keep an eye out for pick pockets.
    • Crowded
    • Only worth it as a way to get to Mercado de la Boqueria
  • Papirum
    • Paper store that sells hand, bound deckled, leather notebooks.
  • Museu d’Art Contemporani de Barcelona
    • Very modern very out there. We did not enjoy this museum. It’s the type of modern art that people sneer at when they think of modern art. Like a banquet table that is set with plates of rice died to look like the flags of various nations, but then they left all the food to rot. Or a wall made out of loaves of white bread.

Sleep

Hotel Praktik Bakery is a hotel with a bakery on the first floor. Sounds a bit gimmicky except that they legitimately have the best bread in the city. There are lines out the door of locals and tourists. You can see the bakers making the bread in the front window. The pastries are amazing, and the grab and go sandwich I got for breakfast was legitimately one of the best sandwiches I ever had.

They do a continental style breakfast, but it’s better to just get something from the bakery directly.

If a bakery doesn’t tickle your fancy, Praktik has other themed hotels in Barcelona, including a wine bar slash hotel.

Oh, and the rooms have rain showers.

All of that, plus a great location.

chrome, tips, GitHub, PR comments edit

Sometimes when I’m working on a long pull request in GitHub and switch back to the PR tab after a while of looking at other pages the Pull Request page will automcaticall reload itself. Most of the time this is fine, but sometimes I wind up losing a lot of state (scroll position, which files were loaded manually, which files had been collapsed, etc). It turns out that Chrome will garbage collect tabs that are taking up a lot of memory that you may not be using. Chrome allows you to disable this behavior by going to chrome://flags/#automatic-tab-discarding. Simply set the drop down to ‘Disabled’.

I typically don’t want to keep this setting once I’m done with my PR, so I’ll then jump into slack and ask it to /remind me to fix chrome://flags/#automatic-tab-discarding in the morning

GitHub Pages, SSL comments edit

Adding a certificate to your GitHub Pages site so that all of your traffic can use HTTPS is easy… if you don’t use a custom domain name. If you do have a custom domain, then you need to do a little work and a (free) Cloud Flare account to get it going.

  1. Create your free acount on https://www.cloudflare.com
  2. Enter your site’s address in the setup bar
  3. Head over to your DNS provider and add the Clod Flare servers as your custom domain servers. e.g. On NameCheap
  4. Optionally, you can head back to Cloud Flare and set up a page rule to redirect all HTTP pages to redirect to HTTPS. Just add a rule to match http://*quintussential.com/*
  5. Wait. DNS has to happen now.

Thanks to Hacker Noon for pointing this out.

mermaid, tools comments edit

Mermaid is a tool that will generate diagrams from a basic definition language.

The mermaid website has full description of the language and features: https://knsv.github.io/mermaid/#syntax

A Simple Example

The following snippet will create a simple sequence diagram.

sequenceDiagram
    Alice->>John: Hello John, how are you?
    John-->>Alice: Great!

The above diagram renders as:

sequenceDiagram Alice->>John: Hello John, how are you? John-->>Alice: Great!

Tools

There are various tools that you can use to edit and save diagrams as images

Mermaid CLI

Pros and Cons

Pros

  • Export diagram as an image

Cons

  • No live updating diagram as you type
  • Syntax requires a non-standard but simple header of ```mermaid

Setup and Use

  1. Install node.js
  2. Install the mermaid npm package
     npm install -g mermaid
    
  3. Install the phantomjs npm package
     npm install -g phantomjs
    
  4. Save the following diagram definition to a file sequence.mmd
     sequenceDiagram
         Alice->>John: Hello John, how are you?
         John-->>Alice: Great!
    
  5. Run mermaid command
     mermaid sequence.mmd
    
  6. Open the image found at sequence.mmd.png

sequence.mmd.png

Visual Studio Code

Pros and Cons

Pros

  • Live updating diagram as you type

Cons

  • No easy way to export diagram as an image
  • Syntax requires a non-standard but simple header of ```mermaid
  • Supports the activate/deactivate keywords that are unsupported by other processors

Setup and Use

  1. Download and install Visual Studio Code (this is entirely different than the “normal” Visual Studio you use to write C# code)
  2. In Visual Studio Code download and install the Mermaid Preview extension
  3. Restart Visual Studio Code when prompted
  4. Create a new markdown file named sequence.md
  5. Paste in the following diagram definition (including the lines that start with three backticks)
         ```mermaid
         sequenceDiagram
             Alice->>John: Hello John, how are you?
             John-->>Alice: Great!
         ```
    
  6. Press <control-p> to bring up the Visual Studio Code command window
  7. Type in > Preview Mermaid Diagram
    • Include the > character
    • You only need to type enough of the command that it shows up in the menu
    • You can type in various short cuts that will also bring up the command quickly
      • > Mermaid
      • > PMD (just the initials)
  8. Click on any of the text in the left pane that is part of the diagram definition

Sample Diagram in Visual Studio

Atom

Pros and Cons

Pros

  • Live updating diagram as you type
  • Export diagram to PNG or SVG

Cons

  • Exported diagram has a blank background (you need to manually open the file and add a non-transparent background to be able to view the image)

Setup and Use

  1. Install Atom editor
  2. Install Mermaid Preview extension
  3. Create a new markdown file named sequence.mmd
  4. Paste in the following diagram definition
     sequenceDiagram
         Alice->>John: Hello John, how are you?
         John-->>Alice: Great!
    
  5. Press the Packages -> Mermaid Preview -> Toggle Preview button
  6. To export as image right click the diagram and select Save as PNG

Sample Diagram in Atom

docker, jekyll comments edit

GitHub Pages have some great features that I’m excited about. Markdown makes writing code-centric blog posts easy. Storing posts in git is great – history, diffs, and no need to learn a new tool. Not to mention simple hosting by GitHub.

There’s just one minor issue, setting up a decent environment on a Windows machine can be troublesome if you’re not alread a Ruby developer. I’ve tried twice now and run into issues both times. Multiple versions of Ruby, non-Windows friendly libraries, failed SSL certs, and probably a few more things that I’ve forgotten. Next I thought I’d try it on Linux on Windows. For the most part that worked well, except some auto-reload features didn’t work well.

It’s almost as if I would be better off trying to run the environment on a Linux machine. Seeing as I don’t have a spare machine and hate running VMs on my work laptop, I’m probably not running Linux any time soon.

All I really want is a preconfigured environment that I can download quickly and not have to do anything to setup. Is that too much to ask? Apparently not. Heading over to Docker Hub, I found several Docker Images for exactly the environment I wanted. I blindly went with the one with the most downloads. There was one minor hicup. The instuctions use the Linux variable $PWD to mount the volume from the host machine to the Docker image. That just needed to be translated to %CD%. With that down, I was able to point the browser on my Windows machine to localhost:4040/ and my website was up. I could edit any file with whatever Windows tool I was comfortable with (ironically, Vim), save it and my site would be regenerated.

All told, I was up and running in about 15 minutes, including download time and writing two simple batch files to start and stop the containers.

StartDocker.bat

@ECHO off
ECHO Starting gpages container

docker run -t --rm           ^
    --name gpages            ^
    -v "%CD%":/usr/src/app   ^
    -p 4000:4000             ^
    starefossen/github-pages

StopDocker.bat

@ECHO off
ECHO Stopping gpages container
docker stop gpages

vim comments edit

I’ve been using Vim for close to 15 years now and it always amazes me. I needed a quick and easy way to encrypt some files on a thumb drive when going from one computer to another. After about 5 seconds of googling I see that as always, vim’s got my back.

First off, you can optionally select your encryption scheme by doing :setlocal cm=blowfish2. There are other options, but that’s the strongest encryption available. Next all you need to do is set the password by typing: :X (note that it is a capital X). You’ll be prompted for the password. After that just close vim as normal. You can cat out your file on the terminal to double check that it’s encrypted.

When you repopen the file in vim, you’ll be prompted to enter the password to decrypt the data.

If you want to save the decrypted file, just clear out the key by doing :set key= and then save the file.

Background

Okay, so I don’t really know why I’d use this, but I just came across Ninject.Extensions.Interception. Basically it allows you to intercept an arbitrary method call and run code before and after the call. Even replace the method entirely.

You could use this to achieve many things you would use Aspect Oriented Programming to do. Post Sharp has a great breakdown on what those use cases are and why it’s a valid approach to solving certain problems.

The canonical use case for this is the ability to easily add logging when you enter and exit a method.

For example, the following code would log all calls to the SomeSuperImportantMehod

[LogAllMethods]
public class CanonicalLogging
{
  public virtual int SomeSuperImportantMehod(string input, int maxItems)
  {
    return CalcualteReallyImportantThing(input, maxItems);
  }
}

And here’s an example of what the output could be

2017-05-05 13:45:54.64723 CanonicalLogging.SomeSuperImportantMehod called with parameters:  {input:  "Hello World", maxItems: 34 }
2017-05-05 13:56:56.94949 CanonicalLogging.SomeSuperImportantMehod returned "42" after running for 11:02:30226

Walkthrough

For the example I’m going to build an implementation of the Dispose Pattern with a base class that will handle all of the actual disposing logic. I’ll use a custom interceptor to ensure that once my objec thas been disposed all future calls to it will throw an ObjectDisposedException.

To get started you first need to be using Ninject. I’m going to assume you have a bit of a background with Ninject. Just in case you don’t, the quick version is that it’s a .Net IoC container. Basically that means that after doing a little configuration you can ask it for an instance of any type you want and it will give it to you, creating it and its dependencies if it needs to.

Another thing to be aware of is that there are two options, either use LinFu or CastleCore for the proxy generation. As far as I can tell, this decision doesn’t really impact much. Just pick whichever framework you like, or one at random. I already use CastleCore in other projects (the Ninject factory extension depends on it), so I’m going with that one.

Install-Package Ninject.Extensions.Interception.DynamicProxy

ADisposable

Next I’ll create the base ADisposable that all of my custom disposable objects will inherit from.

    [Disposable]
    public abstract class ADisposable : IDisposable
    {
        public ADisposable()
        {
            IsDisposed = false;
        }

        ~ADisposable()
        {
            Dispose(false);
        }

        internal bool IsDisposed { get; private set; }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected abstract void OnDispose();

        private void Dispose(bool disposing)
        {
            if (IsDisposed) return;

            if (disposing)
            {
                OnDispose();
            }

            IsDisposed = true;
        }
    }

There two things worth pointing out here. First, the internal IsDisposed property. This will be used by our interceptor later to determine if the object has been disposed. The other thing worth noting is the Disposable attribute. That’s a custom attribute I defined. It inherits from Ninject.Extensions.Interception.Attributes.InterceptAttribute. This is the first step into using interceptors, so let’s take a look.

DisposableAttribute

using Ninject;
using Ninject.Extensions.Interception;
using Ninject.Extensions.Interception.Attributes;
using Ninject.Extensions.Interception.Request;
using System;

namespace Interceptors
{
    [AttributeUsage(AttributeTargets.Class)]
    public class DisposableAttribute : InterceptAttribute
    {
        public override IInterceptor CreateInterceptor(IProxyRequest request)
        {
            return request.Kernel.Get<DisposableInterceptor>();
        }
    }
}

There’s only one method that we have to worry about CreateInterceptor. This just lets the system know what interceptor to use when creating the implementation of ADisposable. You can see here that I added the AttributeUsage to specifically target only classes. Be default InterceptAttributes can be put on anything, although they really only make sense on method (including properties) and class definitions. When the attribute is placed on the class, it impacts all of the methods. In fact there is a neat DoNotIntercept attribute that you can use to exclude certain methods from the class wide interceptor.

In my example, I used the request to get an instance of the Kernel so I could resolve the interceptor I wanted. That was mostly just to illustrate that you can get a hold of the kernel. In this instance, I could have just as easily newed up the DisposableInterceptor. Speaking of which, DisposableInterceptor is where the most interesting code is. We’ll look at that next.

DisposableInterceptor

using Ninject.Extensions.Interception;
using System;

namespace Interceptors
{
    public class DisposableInterceptor : SimpleInterceptor
    {
        protected override void BeforeInvoke(IInvocation invocation)
        {
            base.BeforeInvoke(invocation);

            var disposable = invocation.Request.Target as ADisposable;

            if (disposable != null && invocation.Request.Method.IsPublic)
            {
                if (disposable.IsDisposed)
                {
                    string methodName = invocation.Request.Method.Name;
                    throw new ObjectDisposedException(disposable.GetType().Name, $"{methodName} called after object was disposed");
                }
            }
        }
    }
}

It inherits from SimpleInterceptor and overrides BeforeInvoke. As you may guess, there’s an AfterInvoke as well. If you wanted to, you could set the return value of the method by setting invocation.ReturnValue in BeforeInvoke. Or in AfterInvoke you could check to see if it’s within certain limits.

Anyway, in this example all I care about is overriding BeforeInvoke to check if

  1. The instance being invoked is an instance of ADisposable
  2. The method being called is public (no need to worry about private methods being called since they’d have to be called from public ones to begin with)
  3. If the instance had already been disposed.

In order to do all of those things, I just need to inspect sub-properties of the passed in instance of IInvocation. If all of those things are true, then we just throw an exception.

Now that we see the interception code is straight forward, let’s put it all together so that we can use it.

Sample Service

public interface ISomeService : IDisposable
{
    void SomeMethod(string msg);
}

public class MyService : ADisposable, ISomeService
{
    public void SomeMethod(string msg)
    {
        Console.WriteLine(msg);
    }

    protected override void OnDispose()
    {
        Console.WriteLine("Disposing MyService");
    }
}

The first thing to look at is the sample service interface and implementation. ISomeService is just a simple interface that inherits from IDisposable and has a single method to implement. MyService inherits from ADisposable and ISomeService and pretty much does the minimum it needs to do to implement them.

Notice though that neither of them are aware of either Ninject or any of the interceptors. They are bog standard C# classes.

Resolving an Interface

private static void TestResolvingInterface()
{
    Console.WriteLine("Testing resolving an Interface from the Ninject Kernel");
    using (var kernel = new StandardKernel())
    {
        kernel.Bind<ISomeService>().To<MyService>();

        ISomeService service = kernel.Get<ISomeService>();

        TestService(service);
    }
}

private static void TestService(ISomeService service)
{
    Console.WriteLine("    " + service.GetType().Name); // Prints out "ISomeServiceProxy"
    service.SomeMethod("    Hello World");
    service.Dispose();

    try
    {
        service.SomeMethod("    This call should fail");
    }
    catch (ObjectDisposedException odex)
    {
        Console.WriteLine(odex.Message);
    }
}

In the first method, TestResolvingInterface, we do some very standard Ninject setup. Create a standard kernel, add some bindings, and then resolve our interface. Again, none of this is even aware of the interceptors. Ninject picked up on it from the attribute and that was enough.

The output for this is:

Testing resolving an Interface from the Ninject Kernel
    ISomeServiceProxy
    Hello World
Disposing MyService
SomeMethod called after object was disposed
Object name: 'MyService'.

You’ll notice that service is an instance of ISomeServiceProxy, not MyService. Ninject wrapped our instance of MyService, adding the extra functionality to the proxy without actually impacting our class.

You’ll also see that the second call to SomeMethod does indeed fail with an ObjectDisposedException.

Resolving a Concrete Class

Now that worked all well and good. But what if we resolved just a class instead of an interface? Well that’s where this starts to break down as we’ll see in the code below.

private static void TestResolvingConcreteClass()
{
    Console.WriteLine("Testing resolving a Concrete Class from the Ninject Kernel");
    using (var kernel = new StandardKernel())

    {
        MyService service = kernel.Get<MyService>();
        TestService(service);
    }
}

private static void TestService(ISomeService service)
{
    Console.WriteLine("    " + service.GetType().Name); // Prints out "MyServiceProxy"
    service.SomeMethod("    Hello World");
    service.Dispose();

    try
    {
        service.SomeMethod("    This call should fail");
    }
    catch (ObjectDisposedException odex)
    {
        Console.WriteLine(odex.Message);
    }
}

So now we’re resolving a MyService directly and passing it to the same test function as the previous example. Let’s look at the output.

Testing resolving a Concrete Class from the Ninject Kernel
    MyServiceProxy
    Hello World
Disposing MyService
    This call should fail

We’re getting a proxy wrapping our class again (MyServiceProxy), which is a good sign, but then we see that the second call to SomeMethod actually succeeds. Why is this?

This is probably the biggest caveat in the entire thing. The interceptors can only impact virtual methods. Interface methods are by nature virtual so they are no problem. But when it comes to concrete classes, unless the method is explicislty marked as abstract or virtual it can’t touch them. As I mentioned above, Ninject is dynamically creating an implementation of the requested object with custom implementations of all the methods. If MyService had been sealed, Ninject would have thrown a TypeLoadException when it was resolved because it couldn’t subclass the type.

Summary

As mentioned above, the major caveat is that it only works with virtual methods. If you always use interfaces, then you will be just fine, but if you don’t the interceptors will silently fail to be called.

Other than that, this is a pretty easy to use tool that can provide a lot of power. Another obvious use case for this is automating INotifyPropertyChanged. It’s so obvious that it comes premade. Just check out the NotifyOfChanges attribute.

jekyll, update comments edit

This is my first post on my new blogging engine. I’m using GitHub Pages now. So far I really like it. It’s nice and easy. I have been a big fan of markdown for some time now. Rich text that I can easily create in vim? Yes please! Creating templates for pages and content that I can easily create by adding structured data files to a folder? Yes please!