Become A Better Developer By Indexing Your Brain

This is the fourth post in the teaching and learning series. The teaching and learning series includes the following posts:

  1. All Developers Should Know How They Learn Best
  2. _The Secret Of Being A Great Mentor_**

**__

  1. _The Secret Of Being A Great Apprentice_ ____
  2. _Become A Better Developer By Indexing Your Brain __(this post)___
  3. Learn More – Faster By Using The World-Wide Community
  4. What Playing Cards Can Teach Us About Ramping-Up And Transferring Knowledge

BrainI believe that one of the most important tools or attributes you have as a developer is your memory. I am already hearing people trotting out the old, ‘I don’t need to remember anything, I’ll just Google it’ argument :). It is a decent argument, but I can poke several holes in it without having to think too hard. Aside from the fact that there are still some places out there that will not allow Internet access for security reasons (that’s right you gotta work with no web access – bummer), you will always need to know what you actually want to Google for. Google can’t read your mind (yet :)), you need to remember the concepts your search centers around as well as related information. Hell, you need to remember that whatever you’re searching for exists in the first place. Regardless, you can’t Google everything. You don’t want to keep searching for the basics, or you risk slowing the pace of your work down to a crawl. You can’t Google domain knowledge, it is simply not there to be found, you need to learn it. Not to mention the fact that having a great memory can be damn impressive, try reciting Pi to 1000 places at a party and watch the ladies swoon :).

Seriously though, having a good memory is important. It is valuable in interviews – being able to recall and talk about concepts you haven’t worked with for a while. It is valuable in your day-to-day work – being able to remember what classes do what and which script is executed when. It is an important interpersonal skill – being able to remember names of colleagues, customers etc. There is no doubt, having a great memory will make you a better developer. So, how do you turn your sieve into a steel trap?

Training Your Memory

You’re probably expecting me to say that there is an easy way and a hard way, unfortunately there is only the hard way. Like everything else in life, practice makes perfect and memory is no exception. You need to train your memory to increase capacity, recall time etc. First thing first, you need to memorize crap. Seriously, the first step is that simple, memorize whatever strikes your fancy, poetry, music, code, trivia (even Pi to a thousand places) just make sure you keep doing it. Over time this will make your memory better and better, but it will take a while, fortunately there are some techniques you can use to fake a great memory in the meantime.

Using Mnemonics

Mnemonics are basically memory aids that can help you recall information by association. There are many different ones, some are specific to particular information such as memorizing numbers while others can be generalized to all kinds of information. Here are some common ones:

  • Visualization – associating concepts we want to memorize with parts of a vivid image that we already remember well (such as the layout of your room, or the face of a loved one)
  • Rhyming – making up a rhyme around the concept, thing you want to memorize can help as we are a lot better at remembering rhymes than we are at memorizing random data
  • Chunking – forming data you’re trying to memorize into larger pieces of data that is easier to remember (e.g. forming letters into words, forming words into sentences, forming binary numbers into decimal etc.)
  • The number shape system – associating raw data that is harder to remember with shapes that are easier, in this case associating numbers with shapes so that you have to remember a sequence of shapes (which is easier for our brain to process) instead of a sequence of numbers

Much has been written about all of the above, it is not voodoo science, they really work. The reasons they work are twofold. Firstly, simply by virtue of trying to use a mnemonic technique on a piece of data, you focus on it for a period of time which gives your brain more opportunity to do whatever it does. Secondly, mnemonic techniques are all about associations, you associate your information with various cues; either visual, verbal, musical, conceptual etc. This gives your brain more entry points into the data you’re trying to recall later. How does this help? It is incredibly useful when you use a recall technique called priming. We all do it unconsciously but you can also use it in a targeted fashion.

You’re priming your brain when you’re trying to remember a piece of information and you try to recall anything that you can possibly associate with the data – sounds, smells, concepts etc. It is like building a virtual mind map around the concept you’re trying to recall. The more different associations you have formed with the data the more chance your brain has of finding the information you’re looking for. Simple. I could keep going and going about this stuff and I probably will at a later date :), but for now I’ll leave it here.

In the meantime, if you want to know more about specific mnemonic techniques as well as your mind and memory in general I recommend you pick up a copy of Mind Performance Hacks, which puts together a bunch of these techniques into a cookbook format. However if you don’t feel like reading a book and doing a lot of practice here is a ‘trick’ that I use, which draws from many of these concepts and can give your memory a noticeable boost without too much hard work (if you remember to use it :)).

Your Brain Is A Search Engine

I think of my brain as a search engine. Like any search engine, your brain contains a bunch of data and it also contains an index that allows you to recall this data. You’re constantly bombarded by new information (the web, blogs, books, tv etc.) so adding more data is not an issue, being able to efficiently recall this data is the challenge (your index is more important than your data). According to what I said above, your brain’s index is formed by associating data with a bunch of stuff, you can help out by consciously trying to form these associations. Every time you hear/learn a piece of information you want to be able to recall later (like a name), focus on it for 2-3 seconds and associate it with stuff around you, colors, music, smells, shapes, feelings etc. You want to give your brain a chance to form as many different types of associations as it can. After that just let it go and don’t worry too much about it. In essence you’re trying to piggyback important and hard-to-recall information on sensations and concepts that are less important and easier to recall. That’s all there is to it.

It may not seem like much, but if you do this consistently you will find you can recall things a lot more frequently and easily. You may not be able to impress anyone with a Pi recital, but you will find that after a while people will start telling you that you have a ‘good memory’. So there you go I was wrong, there is an easy way, I guess I forgot :). Seriously though, it is a helpful technique but it is not a substitute for real memory training. Infact in one of those ironic twists that the universe is famous for, the better your memory is already, the easier this technique will be to use. Do you have a favorite memory technique that you use in your day-to-day life? If so please share it with everyone, as always, the more we share, the more opportunity we have to learn and the better off everyone will be in the long run.

For more tips and opinions on software development, process and people subscribe to skorks.com today.

Image by brain_blogger

Ruby Exceptions And Exception Handling

ExceptionRuby exceptions and error handling is not the most remarkable feature of the Ruby language. Infact, the way Ruby deals with exceptions is strikingly similar to other languages (such as Java etc.). But, I think all the stuff I’ve been writing about Ruby lately has taken on a life of it’s own for me :), so I am going to quickly go over this topic if only for completeness sakes.

Raising Exceptions

Getting Ruby to raise an exception is easy :). Ruby, like many other languages has a hierarchy of exception classes (that all inherit from the class Exception), some of these are familiar and fairly easy to produce, for example ZeroDivisionError or NoMethodError. Here is some code which will do just that:

1/0

or

blah = Object.new
blah.hello

Of course you don’t have to wait for Ruby to raise exceptions for you, you can do so explicitly in your code with the raise keyword (it is actually a method). Lets write a method where we explicitly raise an exception if the argument we pass in is false:

```ruby def i_must_have_truth(value) raise TypeError, ‘You must give me truth’ if value == false end

i_must_have_truth false```

this prints:

D:\ruby-projects\scrap\lib\scrap.rb:15:in `i_must_have_truth': You must give me truth (TypeError)
        from D:\ruby-projects\scrap\lib\scrap.rb:18

As you can see we are able to raise a specific exception and pass it a message which then gets printed out to the console. There is also a handy shortcut, if you use raise without giving it a specific exceptions (or even without giving it an error message to display), Ruby will automatically raise a RuntimeException for you which is pretty handy:

```ruby def i_must_have_truth(value) raise “Hello” end

i_must_have_truth false```

this prints:

D:\ruby-projects\scrap\lib\scrap.rb:15:in `i_must_have_truth': Hello (RuntimeError)
        from D:\ruby-projects\scrap\lib\scrap.rb:18

Rescuing Exceptions

So far so good, but life would be pretty tough if we couldn’t handle the exceptions that get thrown in any way, This is where the rescue clause comes in. If we wrap some code in a begin .. end block and put a rescue clause in the middle of that, control will go to the rescue clause if any exception is thrown by the code. Let us demonstrate:

ruby begin 1/0 p 'I should never get executed' rescue p 'I am rescuing an exception and can do what I want!' end

This produces the following output:

"I am rescuing an exception and can do what I want!"

As you can see the first string does not get printed since the division by zero will throw an exception and control will pass to the rescue clause, which will print out the second string for us.

Using rescue by itself will allow you to rescue all exceptions that get thrown by the code, but sometimes you might want to only capture specific ones and let other code handle all the others. The rescue clause allows you to do this as well:

ruby i=0 while i<=10 begin if i ==0 1/0 end raise "random runtime exception" p 'I should never get executed' rescue ZeroDivisionError p 'I am rescuing only ZeroDivisionErrors!' i+=1 end end

which gives us:

"I am rescuing only ZeroDivisionErrors!"
D:\ruby-projects\scrap\lib\scrap.rb:33: random runtime exception (RuntimeError)

As you can tell, we rescued the first exceptions since it was a division by zero, but the second exception does not get rescued and so the program exits with an error. However, we sometimes want to execute some code regardless of whether an exception was thrown or not (i.e. we may want to do some cleanup). Java has the finally keyword for this, Ruby has ensure. We can put an ensure clause within out begin .. end block. The code inside this clause gets executed regardless of whether the code throws an exception. For example, if we are reading from a file, we want to close the file handle no matter if an exception is thrown or not, we can do the following:

ruby file = nil begin file = File.open("blah.txt") raise rescue p 'I rescue all exception and raise new ones' ensure file.close p 'just closed the file' end

as we expect the output is:

"I rescue all exception and raise new ones"
"just closed the file"

Even though an exception was thrown and rescued, the code in the ensure clause executes regardless.

Rescuing Exceptions Inside Methods

If we are inside a method and we want to rescue some exceptions, we don’t actually need a begin .. end block since the method definition itself will act in that capacity. So, we can do something like this:

ruby def some_method p 'Hello method' raise p 'Bye method' rescue p 'Rescuing exceptions' end some_method

which print out:

"Hello method"
"Rescuing exceptions"

We have rescued an exceptions without having a begin .. end block.

You are not limited to knowing just the type of the exception you’re rescuing, you can get more information at your disposal. When you rescue an exception you can get a hold of the actual exception object that was thrown and then query this object for various details. Here is how:

ruby begin raise ZeroDivisionError, "Hello I am a random zero division error" rescue ZeroDivisionError => e p e.message p e.backtrace end

If we execute the above code we will print out the message as well as the stack trace of the exception we rescued which are provided by the exception object itself. You can also do the same thing with a general rescue clause:

ruby begin raise "Hello I am a random runtime error" rescue => e p e.message p e.backtrace end

Finally if you have rescued an exception, but don’t want to handle it yourself (for whatever strange reason), calling raise within a rescue block with no parameters will allow you to re-raise the original exception that you have rescued rather than the normal behavior (i.e. raising a general runtime exception).

Creating Your Own Exceptions

Creating your own exceptions in Ruby is extremely simple, all you need to do is create a class that inherits from Exception or one of it’s descendants and you’re good to go:

```ruby class MyCrazyException < Exception end

raise MyCrazyException, “I am a crazy new exception”```

this prints out:

```ruby

As you can see Ruby is saying that it has raised our new exception rather than one of it’s regular ones. As usual, this allows you to define different types of exceptions for various error conditions in your code which also allows you to rescue them by name. You may or may not want to do this, you can easily get away with just using runtime exceptions but it is up to you.

Update: Several people have pointed out, in the comments that inheriting from Exception directly is a big no-no when creating custom exceptions. You should instead inherit from StandardError. This is because exceptions that inherit from StandardError deal with application level errors, while if you inherit Exception directly you risk catching errors to do with the environment. Also the convention is to end your exceptions with the word Error rather than exceptions e.g.:
class MyCrazyError < StandardError
end```

### The Ruby Exception Hierarchy

If you're curious about the kinds of exceptions that Ruby has predefined for you, here is a list:

Exception
 NoMemoryError
 ScriptError
   LoadError
   NotImplementedError
   SyntaxError
 SignalException
   Interrupt
 StandardError
   ArgumentError
   IOError
     EOFError
   IndexError
   LocalJumpError
   NameError
     NoMethodError
   RangeError
     FloatDomainError
   RegexpError
   RuntimeError
   SecurityError
   SystemCallError
   SystemStackError
   ThreadError
   TypeError
   ZeroDivisionError
 SystemExit
 fatal

You don’t have to take my word for it, you can derive it yourself :). The only thing that is missing from that list is the Errno family of exceptions. These are a whole set of exceptions that relate to file I/O and live in the Errno namespace. You can see one of these in action if you try to open a file that doesn’t exist, e.g.:

ruby File.open("")

which gives you an Errno style exception:

D:\ruby-projects\scrap\lib\scrap.rb:80:in `open': No such file or directory - File not found -  (Errno::ENOENT)
        from D:\ruby-projects\scrap\lib\scrap.rb:80

That’s all, nothing too fancy, just the kinds of basics that everybody needs to know. You’re now a Ruby exception guru, go forth and use your new Ruby error handling powers for good instead of evil :). __

Image by valentin.d

Output Redirection With Bash

RedirectionWhenever you work with bash there are three file descriptors that are always in play and that you need to be aware of. These are, STDOUT, STDERR and STDIN which stand for standard output, standard error and standard input. Normally when programs are executed, unless they explicitly write output to a file, they will output to either standard output or standard error, which means the output will go to the terminal and you will see it on the screen (since both STDOUT and STDERR go to the screen by default). STDIN is where your program will get input data from if you prompt for input from the user. The user enters some data on the screen and your program or script will read it (I won’t say too much more about STDIN).

Of course STDOUT and STDERR are concepts, the actual file descriptors themselves are numbers. When you’re using bash, 1 will be the file descriptor that stands for STDOUT and 2 will be the file descriptor that stands for STDERR. So when you want to redirect the output of a program or script to a file rather than going to the screen you need to change where STDOUT or STDERR (or both) are pointing. To do this you can do the following:

ls -al 1>file1.txt 2>file2.txt

You use the > ‘operator’ to redirect where STDOUT and STDERR are going to write their output by giving the > ‘operator’ a file descriptor and the file you want the output to be written to. In this case nothing will appear on the screen but two new files will be created in the current directory, _file1.tx_t will have the contents of STDOUT and file2.txt the contents of STDERR (of course unless an error actually occurred file2.txt will be empty). If you don’t specify any number e.g.:

ls -al > file1.txt

bash assumes you want to redirect STDOUT, so STDOUT will go to the file you supply, while STDERR will still go to the screen.

But what if you want to redirect both standard output and standard error to the same file. This is easily possible and simply builds on the previous concept. You may have seen the following construct before:

ls -al > file1.txt 2>&1

What this actually means is as follows. We first redirect standard output to a particular file, remember when we don’t specify a number, bash assumes we want to redirect STDOUT:

ls -al > file1.txt

The last bit of the command (2>&1) literally means:

  • take STDERR (i.e. file descriptor 2)
  • and redirect it (i.e. > )
  • to the same place where STDOUT is pointing (&1)

The &1 in the last bit is a little tricky. You may think of the & as a sort-of reference and the 1 is of course STDOUT. So, &1 means – ‘the place that STDOUT is currently referencing’. Since we’ve previously redirected STDOUT to a file this will redirect STDERR to that same file. This is actually the old-school way of redirecting both STDOUT and STDERR to the same place.  There is a shortcut, you simply need to do the following:

ls -al >& file1.txt

which will achieve the same result.

A couple of interesting points to note here.

  1. You can easily turn this redirection around and redirect STDERR first and then point STDOUT to the same place, but this looks a little more clunky since bash can’t assume anything and so we need to specify everything explicitly:
ls -al 2> file1.txt 1>&2

As you can see we redirect STDERR (2) to a file first and then use the same construct as before but swap the numbers around. This is good to know and demonstrates that we understand what is going on, but we probably wouldn’t do this in the wild. Instead use the shortcut version I described above.

  1. When you redirect both standard output and standard error to the same file, you may get some unexpected results. This is due to the fact that STDOUT is a buffered stream while STDERR is always unbuffered. This means that every character of STDERR is written as soon as it is available while STDOUT writes stuff in batches. When both STDOUT and STDERR are going to the same file you may see error messages appear sooner than you would have expected them in relation to the actual output of your program or script. It isn’t anything to be alarmed about but is simply a side-effect of buffered vs. unbuffered streams, you just need to keep it in mind.

That’s all there is to know about bash redirection, always good to be comfortable with the basics. If I’ve missed anything, feel free to fill in the blanks (i.e. leave a comment :)).

__

For more tips and opinions on software development, process and people subscribe to skorks.com today.

__Image by Phillie Casablanca