Sunday, September 24, 2006

Enhance your irb experience on Windows

You can extend the functionality of your irb on Windows by creating a file .irbrc in your %userprofile% directory. Put some Ruby code in there, and they will get loaded when you launch your irb, as well as your script/console. I have put in some code snippets in there to aid my irb experience.

(You may have issues trying to create a file with its name beginning with a period on Windows Explorer. Try to run the command "notepad .irbrc" in your cmd.exe)

Tab Completion

require 'irb/completion'
ARGV.concat [ "--readline", "--prompt-mode", "simple" ]
Do you miss intellisense? If you do this, then in irb, type in like "text".s[tab][tab] will give you a list of methods in String that starts with s.

Ruby Interactive (ri) reference in irb
def ri(*names)
system(%{echo | ri #{names.collect { |name| name.to_s }.join(" ")}})
end
Then you can type ri 'String.strip' to see the Ruby index. The argument has to be a string though.

Remember, on a Windows machine, you have to put "echo | " in front of your ri line or else your irb will just return 'false'. I know it's counterintuitive that it isn't at the end, but it works.

Clear screen
def cls
system('cls')
end
I always wanted clear screen...

Console messed up with long irb lines
If you have a line of Ruby code that is way too long, and you want to go back and make changes, on Windows console it is not very friendly as it will almost guarentee to mess up your edits and disorient your typings. The only way I Googled on how to fix this is to take away the "--readline" switch from the Tab Completion tip above, and replace it with "--noreadline". But then you lose Tab Completion of course. I haven't found a workaround for it yet, but in the mean time I will happily just use Cygwin bash shell =)

Wednesday, September 13, 2006

Ruby constructor dependency injection... or not?

Dependency injection has proven to be something a black belt unit tester must know about if you are serious about unit testing. If you have written some sort of unit tests, would you be jealous if I tell you for some of us, running all these unit tests takes sub-1 second? In C# and Java, actively practising Dependency Injection makes mocking and stubbing out dependencies much easier, and thus tests become easy to write, and run fast because they do not need to make time consuming calls. In fact, constructor injection is one of my favourite design techniques:

    public class Laptop

    {

        private IBattery battery;

 

        public Laptop(IBattery battery)

        {

            this.battery = battery;

        }

 

        public void PowerOn()

        {

            if (battery.Meter >= 10)

            {

                // Booting Vista...

            }

        }

    }



Then to unit test Laptop, you could use NMock like such:

        [Test]

        public void PowerOnFailsWhenBatteryIsTooLow()

        {

            mocks = new Mockery();

            mockBattery = mocks.NewMock<IBattery>();

            Expect.Once.On(mockBattery).Method("Meter").Will(Return.Value(9));

            Laptop laptop = new Laptop(mockBattery);

 

            laptop.PowerOn();

 

            Assert.AreEqual("Off", laptop.PowerStatus);

            mocks.VerifyAllExpectationsHaveBeenMet();

        }



It may not be worth it to mock out Battery, but think about a lengthy web service class.

That's all true in C# and Java. Now in Ruby, I don't even need to constructor inject my Battery instance to unit test my Laptop class. I can just as easily unit test my Laptop class without having to inject my mock Battery:

class Laptop
def initialize
@battery = Battery.new
end
def power_on
if @battery.meter >= 10
# Booting Max OS X
end
end

def power_status
end
end

class LaptopTest < Test::Unit::TestCase
def test_power_on_fails_when_battery_too_low
Battery.any_instance.expects(:meter).returns(9)
laptop = Laptop.new
laptop.power_on
assert_equal :off, laptop.power_status
end
end


Basically I am mocking using Ruby Stubba/Mocha, but I don't even need to write an extra constructor to inject the Class Under Test's dependencies! With no interface IBattery, nothing! This is some cool trickery of programming in a dynamic language like Ruby, and I am discovering these things every day with my colleagues!

I know you are going to say "well, I can use reflection to do the same thing...", and I will tell you, sure, you try to do it in a readable manner and with one line of code. I didn't say you can't do it with C# or Java, I am just saying, this is how I can do it with one line of highly readable Ruby. Happy programming.

Tuesday, September 05, 2006

The most revolutionary usernames and passwords, ever

Haven't you written the authentication piece for your app? Isn't it annoying after it is implemented in your app, every time you try to access your app's functionality during development, you have to start logging in every time by typing in some dev-only user id with a fake password? Having a good set of tests helps alot in terms of not having to go through the app starting from login while new features are still undergoing development, but there are still many cases where you have to debug something starting from the first login page of your application.

Over time, I have developed one way to mitigate this nuisance, by creating a few dev usernames and passwords of the following pattern:

Users:
+ dave
+ fred
+ cat
+ red

Passwords:
+ create
+ database
+ case
+ ware
+ vase
+ card
+ garbage
+ beta

Now the question is, what is the pattern? Answer me in 10 seconds...

That's right, I can finish typing all of them with my left hand, while my right hand still holding my mouse and not have to switch from my mouse to my keyboard to type the password, then my mouse to hit the 'Login' button.

Did you get the pattern in 10 seconds?