Saturday, December 26, 2009

Staging on heroku

I have recently started using Heroku for my small url shortening project called url.misza.co.uk and needed a simple way for staging the code before pushing changes to the production repository.

It is as easy as it gets thanks to git which allows you to maintain connection with many remote repositories.
From within my tyciurl repository I created a new app called tyciurl-staging by calling heroku command line tool. It adds entry for a new remote in your .git/config file and called it "heroku". I renamed to "staging" to better indicate the purpose of this repo. I also renamed my first remote to "live". By doing this I have to explicitly say which remote I want to push my changes to (because I don't have origin any more which is default remote when issuing commands such as git push). This is a small price though for avoiding a mistake of deploying not fully tested changes to production.

Tuesday, December 8, 2009

Linodes available in London

It has been some time since I wrote a blog post. I have (and still am) very busy working on the recent project - multi-tenant e-commerce application for caterers and take-aways.
But couldn't resist to share a good news.
Folks at Linode finally added another location to their excellent VPS offering. It is not only Europe but London, a couple of miles from where I live and just 25ms away!!!
Now I cannot wait for Heroku to do the same thing.

Monday, July 20, 2009

Funny OO of Java Script

During my recent experiments with Java Script I learned how object orientation works in it. It has a very lightweight way of constructing and managing objects. It is confusing at first and many features we know and like such as visibility or interfaces are impossible to use have to be hacked. Below I stress the most important features of Java Script's OO approach.

Cloning as a way of creating a new object

In Java Script there is no class definition. New Object is a cloned version of an object called prototype. Example below shows how it works.


function Parent() {
this.property1 = "Parent property"
}
Parent.prototype.parent_method = function() {
return "Method defined in Parent"
}

Child.prototype = new Parent()

var child = new Child()
child.parent_method()


It is just a copy of the parent assigned to be a prototype for a child which then gets copied whenever you create a new Child object.

Objects are just dictionaries

Objects are just dictionaries and (almost) nothing more than that. You can add and remove properties and there is no explicit property or method hiding mechanism like public/private/... visibility declaration in Java. Ability to easily extend object dynamically happens to be useful in many cases. As an example let me use a service locator I found useful as a way to hide that I had to use global context ;)


// serviceLocator is an instance of a singleton design pattern
var serviceLocator = new function ServiceLocator() {}

serviceLocator.service1 = new Service1()
serviceLocator.anotherService = new AnotherService()


This openness of the object interface may be dangerous though so use if carefully!

Functions are objects

... and because of that may be used in an object (method) or global (function) context or both.


function MyObject() {}

MyObject.prototype.method = function() {
return 'Hello';
}

obj = new MyObject();
func = obj.method;

alert(obj.method());
alert(func());


When used in object context the 'this' variable may be used so properties and other methods of the object may be accessed.

Wednesday, July 1, 2009

The Day of celebration

Today I passed OMG UML Fundamental exam!!!
Although I have been using UML for 4 years, it was a difficult one for me. It is mostly about metamodel and there is not much documentation apart from OMG spec. It is neither short nor easy read but essential to get an understanding of the language internal structure.
I am really pleased with myself and now I can entirely focus on Rails, it's architecture and developing API management application :D.

Friday, June 26, 2009

Understanding Rrails source code - Day 1

Here I start a series of blog posts about my quest to understand Rails source code.
For the last few days I was reading through ruby meta-programming resources and I think that I am ready for rails internals.

First of all I debuged a very simple app to get a feel of what is going on.
I used NetBeans 6.7 RC3 and created a Rails project. It was fine apart from jRuby being very slow starter so I switched in the project properties to the ruby 1.8.7 which comes with my Ubuntu Intrepid Ibex.

It is convenient to have rails source code (rake rails:freeze:edge) within your application so you can change it without affecting anything beyond your experiments. So I did this but after some time my rails instance stoped behave and I had two options:
  • remove vendor/rails and freeze again or
  • start using some version control to make my changes reversible
I chose the second and cloned source code from the github repository into vendor/rails. I could mess around with the code as mush as I liked and was able to quickly revert it with
git reset --hard HEAD
All those debug sessions gave me understanding of some rails details but I still didn't have a clue of the overall architecture of Rails. I knew that it is based on MVC and that it uses ActiveRecord but that was about it. How those patterns are applied I had no idea.
It is a pity that I could not find a diagram visualizing it. Fortunately Yehuda Katz, one of Rails core developers, at the end of his recent post about Rails 3 architecture promised some visualisations showing what is going on under the hood.

Uff, that was a long day with rails and git. Next time on rails architectural big picture and contributing to rails.

Thursday, June 25, 2009

More on Proxy in Ruby

Last week I was impressed how easy it is to create a proxy in Ruby. After some thinking I realized that it is not as good as it looks (at least in some situations).
First of all we don't know what methods are available because reflection does not work as we expect. The quick and dirty solution would be to simulate expected behaviour by redefining SimpleProxy's /((private|public|protected)_)?methods/ and 'respond_to?' methods so it exposes the same interface as the class we delegate calls to.
But does it? What about SimpleProxy.instance_methods? Before we instantiate this class we don't know anything about methods we should be delegating. Obviously one could have created specific class for each class one wants to proxy but this way we are loosing flexibility of our "transparent proxy" object.
There is another disadvantage of using such a proxy - tools won't recognize methods as belonging to the proxy class so you have to have documentation for an object you are hiding behind it on hand.

Thursday, June 18, 2009

Proxy design pattern in Ruby

I have recently started exploring Ruby and it's meta programing features. Just look how straightforward it is to implement proxy pattern :)


class SimpleProxy

def initialize(klass, *args)
@proxee_class, @proxee_class_args = klass, *args
@proxee = nil
end

def method_missing(symbol, *args)
if @proxee.nil?
raise NoMethodError unless @proxee_class.instance_methods(true).include?(symbol.to_s)
@proxee = @proxee_class.new(*@proxee_class_args)
end

begin
puts @proxee.class
@proxee.send(symbol, *args)
rescue NoMethodError
raise NoMethodError
end
end
end

You have to remember that calls to methods already defined on on object will not be sent to the "proxee" so you may need to redefine those to make use cases like the one in the test blow work.

require 'test/unit'
require 'simple_proxy'

class SimpleProxyTest < Test::Unit::TestCase
def test_proxy
name = 'Michal'
friends = ['Eliza', 'Radek', 'Sasha']

proxy = SimpleProxy.new(SocialAnimal, [name])

assert_equal name, proxy.name
assert_nothing_raised(Exception) {
proxy.friends = friends
}

assert_equal proxy.friends, friends

assert_match(Regexp.new("#{friends[0]}"), proxy.to_s)
end
end

class SocialAnimal

attr_reader :name
attr_accessor :friends

def initialize(name)
@name = name
end

def to_s
"#{@name}'s friends are #{@friends.join(" ,")}"
end
end