Posts Tagged Override

MacVim, NerdTree, Janus Annoyances

I’ve decided to use Vim for a few weeks at least and am enjoying it. There are plenty of posts on using Vim as a Ruby IDE and switching from your IDE of choice. Most of the TextMate to Vim posts seem to recommend Janus and for good reason.

Janus adds a number of plugins and settings to Macvim including NerdTree. NerdTree displays a project drawer in a window which is in a vertical split, normally alomgside your working buffer. The first problem is that if you close your working buffer with :bd or :bw, the NerdTree window will fill the MacVim tab, to cycle to the next or previous buffer then entails resizing splits which is not what I want.

Janus solves this with a function in .vimrc:

This function closes the MacVim tab (i.e. Cmd + W) if there is only one tab and it contains 2 windows, one of them with the NerdTree buffer. Unfortunately this doesn’t consider buffers that are not currently displayed. If I want to close MacVim or the MacVim current tab, I’ll use Cmd + Q or W, when I delete a buffer I want the window to display the next buffer.

To disable the Janus function add an override to .vimrc.local:

It’s better to make changes in .vimrc.local and .gvimrc.local as Janus can be updated to the latest version without losing your customisations.

Luckily there is a script on the vim wiki that keeps the window open when deleting a buffer. It can be amended to ignore the NerdTree buffer, if I want to close NerdTree I will use the key mapped to toggle it:

I would like to map :bd to :Kwbd but it seems it can’t be done (I’d be happy to be proved wrong here) so have mapped Ctrl + Shift + B in .vimrc.local:

, , , , , , , ,

No Comments

Entity Classes, IDs and Equality

I want my entity classes to rely on their ID when checking equality, the ID is populated from the repository when I retrieve an object and automatically generated when I save a new entity.

This poses the problem of how I compare two entities before they have been saved while working with them in my domain, or, when I have ‘newed’ them up myself for unit testing. The answer is to use a transient ID.

Normally an Entity Base class might look like this:

public abstract class EntityBase : IEquatable<EntityBase> {

    public virtual int Id { get; protected set; }

    public override bool Equals(object other) {
        return Equals(other as EntityBase);
    }

    public override int GetHashCode() {
        return Id;
    }

    public virtual bool Equals(EntityBase other) {
        if (other == null) return false;
        return other.Id == Id && other.GetType() == GetType();
    }

}

If two new objects are created from a derived class then object1.Equals(object2) will be true as Id will be 0 for both objects. To avoid this I need to check if an object has not yet been saved:

private bool IsTransient {
    get { return Id == 0; }
}

And just check for referential equality if this is the case:

public virtual bool Equals(EntityBase other) {
    if (other == null) return false;
    if (IsTransient) return ReferenceEquals(this, other);
    return other.Id == Id && other.GetType() == GetType();
}

GetHashCode() needs to be overridden to reflect this:

public override int GetHashCode() {
    if (IsTransient) return base.GetHashCode();
    return Id;
}

The full code for EntityBase is:

public abstract class EntityBase : IEquatable<EntityBase> {

    public virtual int Id { get; protected set; }

    private bool IsTransient {
        get { return Id == 0; }
    }

    public override bool Equals(object other) {
        return Equals(other as EntityBase);
    }

    public override int GetHashCode() {
        if (IsTransient) return base.GetHashCode();
        return Id;
    }

    public virtual bool Equals(EntityBase other) {
        if (other == null) return false;
        if (IsTransient) return ReferenceEquals(this, other);
        return other.Id == Id && other.GetType() == GetType();
    }

}

, , , , , , , , ,

No Comments