Also available at

Also available at my website http://tosh.me/ and on Twitter @toshafanasiev

Thursday, 28 January 2010

Making instanceof work for you

When writing generic JavaScript code, you need to be able to handle a wide range of input values and often take different actions based on their type. To detect a value's type, the instanceof operator is often employed, but to varying degrees of success due to a subtlety in its behaviour.

The instanceof operator returns true if the operand to its left is an instance of the object type to it's right ( go here for more detail ), but the results can sometimes be surprising:

// "hi there" is a String, right?
( "hi there" instanceof String ) == false
( new String( "hi there" ) instanceof String ) == true
// sometimes?

The key here is the phrase instance of object type; literal values such as "hi there" and 3.141 are not objects, they are primitive values, or primitives for short, and as such are not instances of any object type, and so do not meet the criteria for instanceof .

The confusion arises from the fact that literals apparently support object instance methods:

// these both work
window.alert( 3.141 .toString() ); // note the gap
window.alert( "hi there".split( /\s+/ )[0] );

JavaScript, like the Java Runtime and the .NET CLR ( and many other VMs ), does something behind the scenes to make calls like the two above legal: it wraps a primitive value in a true Object and applies the instance method call to that object, a process known as boxing.

The fact that JavaScript boxes primitives for method calls but not for instanceof evaluation is a design decision, rather than an error; and armed with this knowledge, we can make instanceof work for us. Here is a little utility function I wrote ( I borrowed the name from a CLR IL opcode ) that I have found very useful:
function isinst( value, type ) {
// box before testing
return new Object( value ) instanceof type;
}

And now:

isinst( 7, Number ) == true
isinst( "hi there", String ) == true
isinst( new String( "hi there" ), String ) == true

Hooray!!

I'm not sure how correct this approach but it works and it's easy to remember.

Monday, 25 January 2010

Removing Subversion bindings

There's no rocket science here, but if you find yourself de-svn-ifying directory trees on an even vaguely regular basis, you'll want some automated way of doing it.

If you use Tortoise SVN ( http://tortoisesvn.tigris.org/ ), and you don't mind copying the contents of the directory you are trying to unbind, a very simple solution is to right click in the directory and choose 'export' from the Tortoise menu ( or use svn export on the command line ) - this will export ( i.e. copy directory structure minus bindings ) the tree to the location you specify. It should be noted, however, that it exports the tree in the state in which it finds it, not a copy of the repository you checked out of - any changes you have made locally are exported ( though unversioned files are not ).

If you want to avoid the copy of an export, or otherwise want to remove the source control bindings in place, a script may be the answer.

I'm not much of a shell scripter and I'm a huge fan of Python ( http://python.org/ ) so I wrote a Python script for removing Subversion ( http://subversion.tigris.org/ ) bindings which I have found so useful that I'm sharing it.

Feedback is extremely welcome, but please use with caution - it does remove entire directories.


'''
this utility script was written by tosh afanasiev.
it comes with no warrantee of any sort.

http://tosh.me/
'''
import os, shutil, stat

SVN_DIR = '.svn'

def remove_bindings( dirname, binding_dir=SVN_DIR ):
    '''
    deletes all svn binding directories in a directory tree.
    a different name can be specified for @binding_dir,
    with the result that 
    directories with that name will be removed.
    '''
    
    # walk the directory
    for root, dirs, files in os.walk( dirname ):

        # test for a binding directory
        if binding_dir in dirs:

            # if found, walk the binding directory
            path = os.path.join( root, binding_dir )
            for broot, bdirs, bfiles in os.walk( path ):
                for f in bfiles:
                    # ensure that all files are writeable
                    os.chmod(
                      os.path.join( broot, f )
                    , stat.S_IWRITE
                    )

            # and finally remove the binding directory
            shutil.rmtree( path )

def main():
    '''
    this function is called if you execute the
    script rather than import it
    '''
    dirname = raw_input( 'directory name:\n' )
    remove_bindings( dirname )

if __name__ == '__main__':
    main()

Thursday, 14 January 2010

Installing IronPython Studio

Right, this is my first blog post - I'm going to jump right in with a brief note on installing IronPython Studio.

I found an excellent resource: http://blog.benhall.me.uk/2008/03/ironpython-studio.html
( thanks Ben ) which really has to take credit for the content of this post - I just wanted my own record of it.

So, here are the steps:
  1. Use the link below to get the Visual Studio 2008 Shell ( isolated mode ) Redistributable
    ( http://www.microsoft.com/downloads/details.aspx?FamilyId=ACA38719-F449-4937-9BAC-45A9F8A73822&displaylang=en ) [tidy, no?]
  2. Run this to unpack the actual installer ( plus license, notes etc. )
  3. Run the extracted installer ( make sure you've closed any VS related apps )
  4. Now go to http://www.codeplex.com/IronPythonStudio to get the VS Shell add-in
  5. Extract and run the installer you found there
More info on extending Visual Studio can be found at http://msdn.com/vsx

That's it, I'd like to find a way of installing the version that integrates with an existing VS 2008 install - but that's for another day.