Sunday, October 28, 2012

Luminance HDR - A Linux HDR tool that I can actually use.

About a year ago, I came across Luminance HDR during a search
for linux HDR tools. I wasn't so impressed back then.

Now, after try Luminace HDR again, I was stunned by the result I get. 
And Yes, I find a Linux HDR tool that I can actually use! 

I took these pictures at Franciscan Monastery, a lost gem in DC.
You will find original photos at the end of the post.


Tuesday, October 23, 2012

Thursday, October 18, 2012

Canon 5D Mark II vs Mark III

First of all, I have to admit that I do not have neither 5D Mark II or Mark III. But I do own a Canon 5D thou. It was a little surprise for me when I heart about Mark III because I was still thinking about upgrade to Mark II.

Don't get me wrong, I love my 5D and I don't need the video features. That why I am still thinking about upgrade to Mark II (and never did). Should I upgrade to Mark III then? or Should I just save some money by upgrade to Mark II? ... Here what I found out:

You can find full spec and full review of Mark II here and Mark III here.

5D Mark II Mark III
Price  discontinue 1,799 3,459
year Aug 2005 Sept 2008 Mar 2012
Photography Features
LCD Size 2.5" 3.0" 3.2"
Max Resolution 4368x2912 5616x3744 5760x3940
(megapixels) 12.7 21.2 22.3
Processor Digic II Digic 4 Digic 5
ISO (Auto) 100-1600 in 1/3 stops 100-6400 in 1/3 stops 100-25600 in 1/3 stops
(manual) 50, 3200 50, 12800 and 51200 50, 51200 and 102400
Auto focus points 9 9 61
Viewfinder Coverage 96% 98% 100%
Continuous Drive 3 fps (60 JPEG, 17 RAW) 3.9 fps (78 JPEG, 13 RAW) 6 fps
Exposure Compensation ±2 EV (at 1/3 EV, 1/2 EV steps) ±2 EV (at 1/3 EV, 1/2 EV steps) ±5 EV (at 1/3 EV, 1/2 EV steps)
AE Bracketing ±2 (3 frames at 1/3 EV, 1/2 EV steps) ±2 (3 frames at 1/3 EV, 1/2 EV steps) ±3 (2, 3, 5, 7 frames at 1/3 EV, 1/2 EV steps)
Muli-exposure no no up to 9 exposures
HDR in cameras no no 5 options
Horizon level no no dual axis leveling
Weight 895g 850g 950g
Memory Card 1 CF 1 CF 1 CF and 1 SD
Video Features
1080 n/a yes yes
720 n/a no 60,50
640 n/a 30,25 30,25
Longest clip n/a 12 mins (approx) 30 mins
Microphone/ Headphone Jack n/a mono/no mono/yes
Audio level ctrl n/a yes (pre recording) yes (while recording)
Aperture control in video n/a no yes
Histogram in video n/a no yes
Chromatic Aberration fix n/a no yes
Time code support n/a no yes

Overall, Mark III is an improvement over Mark II in the photography featrues, little bit bigger censor, faster processor, wider range ISO, more auto focus points, two memory cards, etc. Mark III is greatly improve on HDR support, such as, HDR in cameras, AE Bracketing and Multi-exposure, and 6 fps would help to get better HDR pictures. For me, I wish to have 5 or 7 frame AE Bracketing for quite some time.

Beside HDR, I would say, other improved features are nice the have. It's won't convince me to pay almost double to get Mark III.

Obviously the different between Mark II and Mark III is in video features. I don't know much about it but I can see that Mark III is greatly improve over Mark II. If the video features are important to you, then you should consider Mark III.

On the other hand, if you are looking for your first canon full frame camera, spend some time looking at  Mark II, specially at this price. It is a great photography tools and it is must better than 5D. It come with video features that you can explore. If I am not mistake, Mark II is very successful in this area too.

For me, I already have 5D. I am still happy with it and I don't really need video features. So I probably wait and see how Mark IV is going to look like.

Sunday, October 14, 2012

Setup Keyboard Layout for OpenBox

OpenBox doesn't have a keyboard layout setup program to assist you, as ubuntu or window does. However it is not that difficult to do it yourself.  There are two things that you need to do: add new keyboard layout and show what current layout you are using. The easiest way to setup US and Thai keyboard layout for OpenBox is to add this two commands into you OpenBox autostart file, locale at: ~/.config/openbox/autostart

## enable thai keyboard 
setxkbmap -layout us,th -option grp:toggle
xxkb &
The command setxkbmap is setting layout to US(us) as the first layout and Thai (th) as second. I choose right-alt key to switch the layout by using option 'grp:toggle'. Learn more about other layouts or options, look at the file '/usr/share/X11/xkb/rules/base.lst'. You might want to read resources I listed at the end of the post too.

The second command xxkb will give you a layout switcher and indicator on your panel. Make sure you have the "&" at the end of the line, otherwise the autostart won't finished. The xxkb need a config file '.xxkbrc' in your home directory. Here is mine:

Saturday, October 13, 2012

Observer Pattern In Ruby

Let add one more pattern into the design pattern series by consider Observer pattern. In observer pattern, there is a subject which will be observed by multiple observers. When an event happen with the subject, all observers who registered with the subject will get notify. One obvious example of this pattern is you and my blog. If you are subscribed to my blog, you will get notify when my blogs get updated. This relation between subject and observers provide a clear pattern. It's clear enough to be implemented as a module in ruby standard library, called Observable.

In this post, I am going to use this observable module to implement a program that allow me follow stocks prices, and also calculate the average over time.

Assume that the stock market allow me to read current stock price with a function call "get_current_price(stock_symbol)".  With this method, I can implement a simple class, SimpleStockWatcher, to read the current price and calculate the average as follow:
class SimpleStockWatcher 
  def initialize(symbol)
    @symbol = symbol
    @sum = 0
    @count = 0
  end

  def update
    price = get_current_price(@symbol)
    @sum += price
    @count += 1
    show(price)
  end

  def show(price)
    puts "Symbol #{@symbol}"
    puts "  Time:          #{Time.now}"
    puts "  Current Price: #{price}"
    puts "  Average:       #{@sum/@count}"
  end
end
If I want to monitor Bank of America (BOA), and Google (GOOG), I implement the following loop:
stocks = [ SimpleStockWatcher("BOA"), SimpleStockWatcher("GOOG") ]
loop do
  stocks.each(&:update)
  sleep(1)
end
This loop will print the stocks price and average very second.

Now, I want to add more analysis, say 30 or 100 days moving average. No problem, I add more code into the SimpleStockWatcher. Then every second we get the stock prices, average, 30-day moving average, and 100-days moving average.

Let get a bit more complicate, I want to show only current price and 30-days moving average for stock "BOA". For "GOOG", I want to show current price, the average, and 100-days moving average. How do I satisfy this requirement?

Thursday, October 11, 2012

Transformer Prime and Linux Installer

Android is a great platform for consuming. I means, using it for internet, email, read books, keep your notes, etc. One may go as future as write a book, create art work, edit photos, compose musics, etc. There is an app for every thing you want, even for a linux enthusiastic like me. What I mean is I can use linux side by side with android.

First of all, you can find instruction to install Ubuntu on prime here on the xda-developers site, if you are interested. It's risky, but you will get full ubuntu running on the prime. I won't go into this approach thou. It's not what I aim for.

For me, I prefer another method, chroot to a linux image file. This method allow me to run linux along side with android. I can do things that android does great, like reading email, facebook, websurfing, view pictures, read books, etc. I also can do things that normally android won't allow you. Actually, I can do pretty much every thing that linux provide you.

The idea is to create a linux image file on your android device, mount the image file to android system, and chroot to it.

Guess what, there is an app for that too. It's call "linux installer". Unfortunately, it's some what doesn't work perfectly on transformer prime.

The app work only with rooted device, which mean you need to unlock you prime. After installed linux installer 4.1 (the version at the time this blog is written) from the market to your prime, you have to setup before you can go ahead with installation by select menu and setup. By default, there are couple options are disable. I choose to enable all of them, specially
  • Bind Android
  • Allow write to /system
  • Allow remount with dev/exec
should be turn on. It's make the chroot integrate better with android.

By default, the debian/squeeze is chosen for distribution/version. Don't forget to choose your hostname, and domain name. I leave the chroot launcher script and other options untouched. 

For the loop file location, I leave it at the default location. You should take note where it is. My is "/storage/sdcard0/Linux.loop". It's important that you need to know about this.

For the loop file size, it's need to be above 300MB. However, we are not going to use this loop file anyway, so choose some thing small, say 300.

Tuesday, October 9, 2012

Carpeting and Traffic light - Conclusion

Don't you feel the approach that I used in the previous post, traffic light setting, is a little bit overwhelming? I don't blame you if you do. But it does demonstrate some thing important, it's show what we can do with the problem.

First, with this approach, I always get an answer which may be "no, I can not do it in 3 turn per cycle" or "yes, I can". Not only that, I get a specific light setup, a pretty good one. Even with more complicate situations, say bigger intersections, I still definitely get an answer.

I also know that there is no way to let every one pass through safely only 2 turns per cycle, no matter how much I try. It is definitely good to know your limit, isn't it?

Moreover, if I have a problem that have hundreds of directions. Once I turn the problem to a graph, I probably going to look up a solution of graph coloring, which suit my case, or use one if it's already out there. Either way, I have a pretty good idea how to solve my problem.

You probably realize by now that I am using mathematical abstraction, a graph, to help us to understand, learn more about limitations and provide a solution to the problem.

This concept is important in computer science, because when you try to solve problem with computers, you actually turn a real problem into an abstract problem in computers. Mathematics give you a good guide line now to implement these abstractions. This what you are going to learn when you go to collage for computer degree, learning to solve problem using mathematics, and learn how to implement it in computers

Sunday, October 7, 2012

Carpeting and Traffic light, what do they have in common? - Part 2

In the previous post, I define a carpeting problem. It quite a simple problem that can be described, including a solution in couple paragraphs. The traffic light problem is quite more complex.

Traffic light setting: I want to setup a traffic light on a intersection (figure 1), which A, B, and C are two-way streets, while D is a one way street, and have to make sure that every one can get thought the intersection safely.

figure 1
If I setup the light as follow:
  1. let A go to B and C, and block every one else
  2. let B go to A and C, and block every one else
  3. let C go to A and B, and block every one else
  4. let D go to A, B and C and block every one else.
There will be 4 turns signal for each cycle. I  ensure that every one get their turn, and pass through the intersection safely. 

You may notice that while we let A go to B and C, in the same time C can safely go to A. This raise the question, can we do 3 turns signal in each cycle, and still let every one get through safely?

Carpeting and Traffic light, what do they have in common?

Nothing ... you may say so. And I completely agree with you. However, what I am talking about is two problems, Carpeting a house and Traffic light setting. They may have some thing in common that might surprise you. I have to be more specific, haven't I?

Carpeting a house: I want to fully carpeting this house with one condition. I want every room that connect to each other have different color. For the room that is not directly connect, may share the same color.

figure 1
For this particular house, kitchen (K) and living room (L) are connected, they have to have different color. Assuming the small area in front of rest room (R) is belongs to kitchen. All bedroom (MB, B1 and B2) can have the same color. In this case, 3 colors is enough. But can I do this with two color?

Remember the small area in front of restroom is belongs to Kitchen, so B1 and B2 are not directly connected, so living room.
figure 2

Let draw this floor plan differently (figure 2):  All the room are connected directly to kitchen, except the master bedroom (MB). We have to choose two different colors for kitchen and living room, say C1 for kitchen and C2 for living room. Then we can use C1 for master bedroom and C2 for bedroom 1 and 2. Using two colors is possible then.

Saturday, October 6, 2012

Square Photography

Look interesting right? :)
It change my perspective. Why don't you try it!


 

Friday, October 5, 2012

Rails Namespace, Nested Resource and form_for

Couple days ago, I ran into a problem when I try to use namespace, nested resources and form_for in Rails 3 and ruby 1.9.3. I try to setup some thing similar to this, a namespace :admin, with nested resources :menus, and :menu_items. Here is the routes.rb:
namespace :admin do
  resources :menus do
    resources :menu_items
  end
end
I think it's probably common used case. Unfortunately, I got this error when I try to create a new MenuItem in menu_items/_form.html.erb
undefind method 'admin_menu_items_path' for #<#<Class ...
...
 1: <%= form_for(@admin_menu_item)do |f| %>
      ...
17: end
I realize that the standard scaffolding won't work for me, so I start googling. Right away, I get a lot of hits. It's seem to be a common issue. However, the solutions create quite a confusion for me. I try different solutions, some looking good but don't work! .. Here is what I find working.

 First, in admin/menu_items_controller.rb, method 'new':
def new 
  @menu = Admin::Menu.find(params[:menu_id])
  @menu_item = @menu.menu_items.build
  ...
end
It load up the @menu, and build @menu_item, nothing surprise me. I also get rid of than "admin" prefix. It's simpler that way.

Thursday, October 4, 2012

Permutation and Mathematical Induction

Last post, I show how basic mathematical induction works. Now, I am going to use it to prove that an algorithm is work correct. In this case, we are going to prove a permutation algorithm, which take an array of unique numbers L, and return an an array of all permutations of L. Let call it perms(L). For example:

  1. If L = [ ], then perms(L) would be [ [ ] ].
  2. If L = [1, 2, 3], the result of perms(L) will be an array [ [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]. Note: the arrary could be any order.
The algorithm that I am going to prove is shown here:
 1: def perms(L)
 2:   return [[]] if L.size == 0
 3:   result = []
 4:   L.each do |elm|
 5:     L1 = L - [elm]
 6:     perms(L1).each |p|
 7:       p1 = [elm] + p
 8:       result << p1
 9:     end
10:   end
11:   return result
12: end

The exact statement that I want to prove to you is: for any given array L of size n, the perms(L) is an array of all size-n permutation of L.

First, basis step: Let L = [ ]. The L.size will be 0. Then the perms(L) will return immediately with value [ [ ] ], which is the array of all size-0 permutation of L.

Inductive step: Let assume statement is true for any array with size n. We have to show that for any array L of size n+1, perms(L) will return an array of all size-(n+1) permutation of L.

Wednesday, October 3, 2012

Chinese Abacus and Mathematical Induction

When I was a kid, I used to practice Chinese Abacus every day. Me and my brother turn this boring practice into a competition, and the winner is the person who can do 1 + 2 + ... + 100 faster! Of course, it's has to be correct. At that time, we were told that the correct value is 5050, and we did not question about it.

Now, I kinda wonder, if I am going to proof to some one that 1 + 2 + ... + 100 = 5050, how can I do that?  Here one way to do it.

First line up two line of sum this way, one from 1 to 100, another from 100 to 1.

  1 +   2 +   3 + ... + 100
100 +  99 +  98 + ... +   1
---------------------------------------
101 + 101 + 101 + ... + 101 = 101 * 100

Then, sum each column. As you can see, sum value in each column is equal 101. Since we know that there is going to be 100 column. So the sum of the last line, which is sum of those two line, is 101 * 100. Because we start with 2 lines,  the sum of  \(1 + 2 + 3 + ... + 100\) = \(101 \cdot 100 / 2 = 5050 \).

This way, we can also show that, for any given interger \(n \ge 1\)
$$ \displaystyle\sum_{i=1}^{n} i = 1 + 2 +  ... + n = \frac{n\dot(n+1)}{2}$$
Nice!, It's probably require a genius to come up with the proof like this, don't you think?

Another way, we can use mathematical induction to proof this statement too. It's more systematic, and can be generalize to prove more complex statements. The proof by mathematical induction has two parts, basis step and induction step. Basically, we have to show the basis is true, then show if any given number is true, then the next one also true.

Tuesday, October 2, 2012

Writing Math Equation in Dynamic Page Blogs


Mathjax is an open source Javascript display engine for mathematics. It's allow you to rendered math equation on all modern browsers without have to download reader, plugins or fonts.

Mathjax support Tex, LaTax and MathML equations. Better than word, here is an example.

When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) 
and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

Which produce:
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

What not so trivial to me is how to set it up.  Basically, to endable MathJax in web platform, you have to add the line to header section.
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?
config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>

Unfortunately, it's won't work with Dynamic Page, which I am using. Because the content of the post is showed in a popup page, the in the main page itself. The solution, the script have to be added into the post itself.

Here what I did:
  1. open the post
  2. edit in html mode
  3. copy the script on top of the post
Then start writing the math equation! That all it's take.

Mathjax has an excellent documentation how to use it here. It's really cool! :)

Monday, October 1, 2012

Favor Composition over Inheritance - Conclusion

It all come down to the word "change". Change is the key to decided which one should be inherited and which one should be composite.

The base class Duck has-a name, and swim. So does the MallardDuck which inherited from Duck. It is-a Duck after all. MallardDuck also has-a behavior fly and quack.  But these two behavior are not inherited from Duck thou. Both are composite part of MallardDuck.

What make swim, different from fly? Can we consider swim as a behavior, and implement it in the same way as fly?
The answer is in the word "change". The swim does not change. All subclass has the same swim method. While, fly and quack are not the same in all subclass. Of course, nothing prevent us from implementing swim in the same way as we did with fly. But why do we need to do more complicate code if we don't need too. Inherited would work great for swim.

Can we just override and make change in the subclass as needed? 
Yes, we can. However, if the change are the same in two different subclass, then we code duplication! Consider, both MallardDuck and RedheadDuck can fly with wing. That means we would have to make the same change to MallardDuck and RedheadDuck. By implement the part of the duck that can be changed into module, we can pick and choose what behavior we want. You can see in the part 3, it is make much more sense, easily to understand and maintain.

Object vs Module, which one should I use?
Obviously, if you want ability to change the behavior at run time, you would have to use object approach. But that is not the only advantage object approach has over module. The object give you much control over namespace and help you avoid name collision.

Consider the module implementation, when we include the module, all the methods are defined in the same name space. Which means it's possible we can get name collision.  Specially, if the module are large, and very complicated, say 10 or may be 20 methods defined. It's possible two modules have the same method name but doing different thing. For example, if we happen to include both Behavior::FlyWithWing and Behavior::NotFly, one of the fly method will get overridden.

On the other hand, if we implement using objects, it's name collision won't happen, because all the methods would be contained in the object itself.

For the problem that is not so complex, the module would be a good choice, because it's easier to understand, and manage. Beside, with good naming convention, the name collision can be avoid easily.

Knowing when to use inheritance or composition is one of the most important skill to learn. What every way you choose to implement, separated part of the object that can be change, and use them to compost the new object is the key to handling change. If it's not change, just inherited it!

Always, start with the simple solution, but also know where are you heading help you make the right choice.

Thanks for reading this far. :)

Sunday, September 30, 2012

Favor Composition over Inheritance - Part 4

Previously in the programming series posts, I show how to use module to implement composition. One limitation of using module is, duck can not change behavior at run time. Such as MallardDuck can only fly with wing. How can we allow an instance of duck to change their behavior at run time? An answer is using object instead of module.

 To support this feature, the base class, now, hold all the behaviors  implemented for subclass. That quite different from using module, which the base class know nothing about subclass behaviors at all.
class Duck
  attr_reader :name
  attr_accessor :fly_behavior, :quack_behavior
  def initialize
    @name = "mallard duck"
    @fly_behavior = nil
    @quack_behavior = nil
  end

  def fly
    fly_behavior.fly
  end

  def quack
    quack_behavior.quack
  end
end

In this case, the base class by default has no behaviors. It's the subclass job to create, and assign default behaviors of the subclass when initiate an instance. For example, MallardDuck default behavior for flying is fly with wing, etc.
require './duck'
require './behavior/fly_with_wing'
require './behavior/quack_loud'

class MallardDuck &lt; Duck
  def initialize
    @name = "mallard duck"
    @fly_behavior = Behavior::FlyWithWing.new
    @quack_behavior = Behavior::QuackLoud.new
  end
end

Cherry Blossom 2012

Pictures from Cherry Blossom this year. I like to see how it's show up in the blogs. Not so bad :)



Saturday, September 29, 2012

Favor Composition Over Inheritance - Part 3





In part 2, I implement Duck with fly behavior. Now, I am going show how to add new behavior, quack . Let say, I want to add two quack behavior, Behavior::QuackLoud and Behavior::QuackSilent. Similar to fly behavior, each behavior is implemented in module, and put under directory [behavior].

...
 |+[behavior]
   |-...
   |-quack_loud.rb
   |-quack_silent.rb
The Behavior::QuackLoud is implement in quack_loud.rb module as shown here:
module Behavior
  module QuackLoud
    def quack
      puts "quack loud"
    end
  end
end
It's not hard to see how Behavior::QuackSilent is implemented.

Now, I want MallardDuck, which already be able to fly with wing, also can quack loudly. All I have to do is include Behavior::QuackLoud in the class MallardDuck. Of course, I need to require appropriate file:
require './duck'
require './behavior/fly_with_wing'
require './behavior/quack_loud'

class MallardDuck < Duck
  include Behavior::FlyWithWing
  include Behavior::QuackLoud
  ...
end

In the same way, I can define duck that can fly but not quack, or duck that can not fly but quack loudly. Different duck with different behaviors can be defined by including appropriate behavior module. A particular behavior defined in one place, and can be easily shared between different class of duck. As you can see, it's easy to understand, implement, and maintain.

Let recap a bit: Share behavior of all kind of Duck are implemented in base class. Then different behavior are separated out into modules, and then get included into class definition when that class need  it. We can say, duck class is composed with different behavior module.

Here, how the composition is done in ruby using module!

Next time, I will use different way of implementation to allow a duck to change behavior during run time. It's would be fun!

Note: Amazon Prime & Flash



I migrate from Xbuntu to Crunbhbang Linux a couple days ago. Until today, I have not have a chance to test amazon prime video service yet. I try today, and guess what I can not watch video any more.

I look around for solution, and found this Ask Ubuntu page, which intern point to the Adobe support page that contains the solution. I make a copy over here for my own reference :)

Prerequisites for protected content playback


For Ubuntu 10.04 or later, ensure that the Hardware Abstraction Layer module is first installed using apt-get.
(Watch carefully for “hal” install errors, as a damaged package install can continue to affect video playback.)
sudo apt-get install hal
After the "libhal" (HAL) library install completes, close the browser and clear the Adobe Access directories by executing the following shell commands:
cd ~/.adobe/Flash_Player
rm -rf NativeCache AssetCache APSPrivateData2
Note:
If the Hardware Abstraction Layer module is missing, Flash Player still functions. However, it cannot play protected content that requires the Adobe Flash Access DRM (Digital Rights Management) module.

Note: Buildroid for VirtualBox

With is Buildroid for VirtualBox, I can have android 4.0.4 running on VirtualBox. All you have to do is download the ova file, one of the open visualization format. Import the file to VirtualBox, and turn it on!

It's good for the development, that for sure. If you like, you can just play around with it.

Crunchbang Linux and VirtualBox

Crunchbang is base on Debian. However, the virtualbox is a well known issue with crunchbang. When I try to install virtualbox from the repository (the OSE - Open Source version), it won't work out of the box. A quick googling, you would find couples link related to this issue.

One solution is to install official Oracle version, which you can follow the instruction found here: VARIOUS VIRTUALBOX INSTALLATION.

Unfortunately, after adding new source and apt-get update. I got this error messages:
W: GPG error: http://download.virtualbox.org wheezy InRelease: 
The following signatures couldn't be verified because the
public key is not available: NO_PUBKEY 54422A4B98AB5139

After quick googling again, I found this page, which provide me a solution:

gpg --keyserver pgpkeys.mit.edu --recv-key 54422A4B98AB5139
gpg -a --export 54422A4B98AB5139 | sudo apt-key add -

I believe that allow me to update Debian APT key. After these steps done, I can continue and finished the virtualbox installation. Anyway, before install virtualbox-4.1, I do "apt-get search virtualbox", and found that 4.2 also available. I just simply install 4.2 instead of 4.1.

Favor Composition Over Inheritance - Part 2

In previous post I show how to do composition using Ruby Module. It's quite natural and easy to do. I also mention Ruby Convention on class/modules code organize, but I have not made it clear what it really means. Let get into this topic today. If you have not read the previous post , I recommend skim though it to get the idea.

By following ruby convention, each class have it own separated files. The namespace become a sub-directory, which contains module files. In this case directory behavior contains different fly behavior
+[duck_app]
 |-duck_app.rb
 |-duck.rb
 |-mallard_duck.rb
 |-redhead_duck.rb
 |-toy_duck.rb
 |+[behavior]
   |-fly_with_wing.rb
   |-not_fly.rb

The duck_app.rb is the main application which using ducks class. Here how it's look like:
require './mallard_duck'
require './redhead_duck'
require './toy_duck'

ducks = [MallarDuck.new, RedheadDuck.new, ToyDuck.new]
p ducks.map(&:name)
ducks.each(&:swim)
ducks.each(&:fly)
In this case, we simply ask their name. Let they swim and fly.

In order to use class MallardDuck, we have to tell ruby where is the MallardDuck definition are, by using "require" statement as showed. Similarly, in the mallard_duck, which reference to Duck, and Behavior::FlyWithWing symbols, we use 'require' statement to load the symbols definition:
require './duck'
require './behavior/fly_with_wing'

class MallardDuck < Duck
  include Behavior::FlyWithWing
  ...
end

With this convention, the code is organized into well defined places, which make it easy to find things.

That's it, for today!

Thursday, September 27, 2012

Favor Composition Over Inheritance

I have been reading "Head First Design Patterns" [1], which used Java to construct all examples. It's made me wonder what would it take to implement same pattern in Ruby. What would be the different, specially Ruby is not "type" language at all.

The first pattern that I am going to try is "Strategy" pattern. The principal behind "Strategy" pattern is "Favor composition over inheritance". It's interesting to see that at least two different way we can implement this principal in Ruby. One using module, another using class.

Let use the same design in the book, the duck design. Since all duck would have name, and can swim. The Duck base class would contain attribute name and method swim(). All duck swim, you know.
class Duck 
  attr_reader :name
  def initialize
    @name = "simple duck"
  end

  def swim
    puts "All duck can swim."
  end
end

However, not all duck are fly in the same way. MallarDuck and RedheadDuck will be able to fly with wing, while ToyDuck won't be able to quack or fly at all. To be able to share same behavior between MallardDuck and RedheadDuck, we create a module under then namespace Behavior
module Behavior
  module FlyWithWing
    def fly
      puts "Fly with wing"
    end
  end
end

module Behavior
  module NotFly
    def fly
      puts "no way I can fly"
    end
  end
end

class MallardDuck < Duck
  include Behavior::FlyWithWing

  def initialize
    @name = 'Mallard duck'
  end
end

class RedheadDuck < Duck
  include Behavior::FlyWithWing

  def initialize
    @name = 'Redhead duck'
  end
end

class ToyDuck < Duck
  include Behavior::NotFly
  def initialize
    @name = 'Toy duck'
  end
end

irb> ducks = [MallardDuck.new, RedHeadDuck.new, ToyDuck.new]
irb> ducks.each(&:fly)
Fly with wing
Fly with wing
no way I can fly
With proper directory setup, and follow convention. Ruby will be able to find the file that contain module and include it properly with no configuration at all.

In this case, each module would contain in each file under directory "behavior". By ruby convention, filename would have to match the module name. That mean the file would be name "fly_with_wing.rb", and "not_fly.rb"

We can also do the same with "quack" behavior, say Behavior::QuackLoudly, Behavior::NotQuack, etc.

As you can see, we can use ruby module to implement composition quite efficiently. It's seem natural to me to use module to break down object into different component and composed them.

Next time, I will describe more in detail of the implementation.

[1] Head First Design Patterns, Eric Freema, Elisabeth Freeman, O'Reilly 2004.