10 Apr 2012

Corey Haines - fast rails tests [video]

Corey haines talking about writing faster tests in rails. Requiring
spec helper into your tests will spin up an instance of rails before
running your tests, this is slow and boring. Corey runs through a few
techniques of how he isolates code by leveraging on Ruby itself rather
than Rails.

http://arrrrcamp.be/videos/2011/corey-haines---fast-rails-tests/

9 Apr 2012

Good things come to those who wait. Or...

Media_http28mediatumb_hkeio
27 Mar 2012

Avoid "just another side project"

Ok, so say an idea pops into your head, and you have that light bulb moment!  You carry on about your day, and somehow you start thinking about the idea again, but this time with a bit more flesh, and you start asking questions to yourself.  This happens several times throughout your day.  Maybe you jot it down in your pad or a piece of paper for later.

After more deliberating, you sit down and say, ok, I'm going to start a project.
What do you do?

I under stand the practice of MVP, proving assumptions, failing fast.  But that leads you to just jump into code and start prototyping before you've fully fleshed out the idea.

So, before you type,
rails new my_new_project

Write a read me, just a few paragraphs, to describe the idea, whom will use it, how will they use it.  Use personas and write a scenario extract.  Identify the problem!
By doing this, it will make you think about the problem at a deeper level.  You will begin to ask yourself more questions.

I did just this, with my most recent idea.  When I was done with the read me, I sat back and asked myself, is this exciting/interesting enough for me to see through.
The answer was no!

What do you do when you come across this situation? How do you avoid starting another project before finishing the last?  I'd love to hear your thoughts, comments and experiences.
17 Mar 2012

Untangling Ruby modules

I came across a bug recently where an object mixed in 2 separate modules, but they both had a method name that was identical.  The method was invoked but it's was invoking the wrong method.

module Practical
    def test
        "I'm taking my Practical test"
    end
end

module Theory
    def take_test
        test()
    end 
 
    def test
        "I'm taking my Theory test"
    end
end

class FirstDrivingLesson
    include Practical
    include Theory
end

class SecondDrivingLesson
    include Theory
    include Practical
end

The two driving lesson objects, include the modules in different orders.  From the results below, we can tell this affects what module gets called first.

FirstDrivingLesson.new.take_test 
=> "I'm taking my Theory test"
SecondDrivingLesson.new.take_test 
=> "I'm taking my Practical test"

If we inspect the corresponding object's ancestors, it reveals the order modules get pushed into the ancestor stack.

FirstDrivingLesson.ancestors 
=> [FirstDrivingLesson, Theory, Practical, Object, Kernel, BasicObject] 
SecondDrivingLesson.ancestors 
=> [SecondDrivingLesson, Practical, Theory, Object, Kernel, BasicObject]

So when a method is invoked on an object, it searches self to see if it exists, if not, it will start going up the ancestor stack and invoke the method the first time it's found.
13 Mar 2012

Ruby: Symbol#to_proc

The to_proc method on the symbol, simply converts the symbol into a Proc object and invoking itself 
class Symbol
  def to_proc
    Proc.new { | x | x.send(self) }
  end
end

The Proc object (short for procedure), is just a block of code, bound to a variable.

So instead of declaring a block, to invoke a single method 
['james', 'jessie', 'emma'].map { | name | name.upcase }

 You can use Symbol#to_proc
['james', 'jessie', 'emma'].map(&:upcase.to_proc)

or the more cutdown version
['james', 'jessie', 'emma'].map(&:upcase) 

 
13 Mar 2012

Ruby: debugging 'train wrecks' with tap()

I've just uncovered the tap().  It can be used to simply debug chained methods.

Given the following statement:
[1,2,4,[3,8,[5,2,5,7]],4].flatten.sort.join('t')

To uncover what the result of sort, you don't have to break the chain and reconstruct it
temp = [1,2,4,[3,8,[5,2,5,7]],4].flatten.sort
puts temp
temp.join("t") 

Just add tap to the chain with a block,
1,2,4,[3,8,[5,2,5,7]],4].flatten.sort.tap {|i| puts i}.join('t')

I'm not a fan of 'train wrecks' but it seems to be a Ruby idiom, and rubist love their DSL's
12 Mar 2012

Ruby private method != inaccessible

So after playing about with Object#send I discovered that I could access private methods from outside the object.  This doesn't seem right to me, but I'm sure there's a thread debating this on the mailing list.

So given an object

class MyObject
  private
  def hide_me
    puts "shh... I'm hiding"
  end
end

In irb, I create a new instance of the object
foo = MyObject.new
 => #<MyObject:0x000001009e78d8> 

Try to access the private method from the instance, but get a NoMethodError, rightly so!
foo.hide_me
NoMethodError: private method `hide_me' called for #<MyObject:0x000001009e78d8>
from (irb):8
from /Users/tonyto/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `<main>'

But passing the private method as an argument to send, makes my private method no to private!
foo.send(:hide_me)
shh... I'm hiding
 => nil 
12 Mar 2012

surround.vim

Surround.vim is all about "surroundings": parentheses, brackets, quotes, XML tags, and more.

csw"        =>      To surround a word with quotes
cswtP>    =>      To surround a word with a tag

cs"(         =>      To change the surrounding quote to brackets

ds(          =>      To remove the surround bracket

yss$         =>     Wraps the whole line with a $
ySS"        =>     Wraps the whole line in quotes and puts it onto a new line indented
5 Mar 2012

Backbone koans

17 Feb 2012

Cooking mono with Vagrant and Chef

Vagrant is a tool for building and distributing virtualized development environments, and that's exactly what I'm planning on using it for.
I wanted to build a VM ready for mono development and distribute it within my team.
Vagrant is packaged as a RubyGem, so if Ruby's installed, it's pretty easy to get started (check out their site).
Veewee lets you build a custom base box from a wide range of OS. It's a RubyGem too, so install it along with vagrant then,
vagrant basebox templates
should list all the base boxes veewee supports.
The github readme explains how to create your own base box.  I wouldn't recommend building a windows server basebox, it's time consuming and I didn't see the light at the end of the tunnel.
Once you've created your basebox, run the following to get up and running,
vagrant box add base PATH_TO_YOUR_BASE.box 
 vagrant init
vagrant up
By default, the VM runs headless, so you can ssh into the VM,
vagrant ssh
Chef or Puppet can be provisioned with vagrant, just edit the VagrantFile and tell it where the cookbooks or manifests are.

Reload the VM, and it should spin up again with the configurations in place.
Mono
I haven't quite figured out chef, and my innovation time was closing to an end, so to test the concept, I've hacked up a bash script to configure and install the bare bones of mono and added it as a recipe in the chef cookbook.
Grab a project, run xbuild at the solution level and you should be cooking on gas.
I've barely touched the surfaces of chef, so to follow up, I'd like to learn more about chef and test it's limits and potential.

 

Tony To's Space

I'm a software developer interested in Ruby, Node, Javascript, c#, html5 web apps, realtime web, lean startups and customer development/UX.

I also love to eat tasty food, drink coffee, listen to music, cycle, snowboard and workout.