Friday, January 28, 2011

On Continuous Learning

So, a couple of Fridays ago I injured my right wrist snowboarding in Breckenridge, Colorado, and the doctor put a cast around my arm because I got a hairline fracture in the bone connecting to the wrist. Given that I do not have the dominant hand available for use anymore, I had to get by without it for the last two weeks, and will continue to do so for weeks to come. As a result, I had to learn how to do several things left-handed, and that got me thinking about Obtiva's culture of Continuous Learning and how it benefited the process.

Normally, I would have been discouraged and handicapped for weeks, probably using my injury as an excuse not to do some tasks and constantly complain. Given the new habits ingrained in me after being with Obtiva for 5 years now, I surprised myself by having a totally different attitude:
"Why should learning anything with my left hand be any different from learning a new language, library, or technology? Couldn't I follow the same process of gradual learning with "beginner's mind" (as mentioned in Dave Hoover's book Apprenticeship Patterns)?"

And so I did, and as a result, I learned how to do quite a few things with my left hand that I could not do with it before:

Eating with chopsticks fast enough not to starve:

Using a TrackPad comfortably:

Diagraming and writing on a whiteboard quickly enough to effectively relay ideas to my coworkers:

Drumming with one hand:

I am very grateful to Obtiva for instilling the Continuous Learning culture attitude in us, and would like to encourage everyone else to have that spirit instead of letting negativity pose as "being realistic" whenever you are learning something new, especially under difficult circumstances.

Thursday, January 27, 2011

Rails Dragonfly Image Upload With S3 and Test Faking with Fakeweb

A while ago, I wrote a post titled "Faking Paperclip S3 calls with Fakeweb". Since then, while working with the Rails CMS Refinery, I discovered the delights of using the simpler Rack integrated Dragonfly library for easy upload/processing of images in a Rails web application.

Here is a guide on how to set Dragonfly up to work with S3, and how to fake its Cucumber integration test calls with Fakeweb.

Assuming you already have Dragonfly configured for use by their GitHub Instructions, edit the Dragonfly initializer and add the following line:


app.configure_with(:heroku, ENV['S3_BUCKET'])


Note that it is a bit quirky that we are referencing heroku here, but all what that Dragonfly config file does is configure S3 storage to read environment variables. There are other more verbose ways of doing this that are also easy, but using that one line is easiest. In the future, it is worth contributing a config file to Dragonfly that has a better name than heroku for configuring S3.

Next, edit your Rails 3 application.rb file and add the following above your application module:

ENV['S3_BUCKET'] = "APPLICATION_BUCKET_NAME_#{Rails.env}"
ENV['S3_KEY'] = "S3_KEY"
ENV['S3_SECRET'] = "S3_SECRET"


Assuming you are using Bundler, edit Gemfile and add the following:


gem 'rack-cache', '1.0.0', :require => 'rack/cache'
gem 'dragonfly', '0.8.1'

group :test do
gem 'fakeweb'
# other test gems go here
end


Now, add the following step to your general steps file:


When /^(?:|I )attach the image "([^\"]*)" to "([^\"]*)"$/ do |file_path, field|
base_path = "http://s3.amazonaws.com/"

path = "^#{base_path}#{ENV['S3_BUCKET']}/([^/.]+/)*#{File.basename(file_path)}$"
FakeWeb.register_uri(:put, Regexp.new(path), :body => "OK")

body =<<-endstring
<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ListAllMyBucketsResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Owner><ID>cc51eabc6701f10ce998d1c4acce7e3b1dc5510ac392a24257c59922514c7baf</ID><DisplayName>S3_USER_NAME</DisplayName></Owner><Buckets><Bucket><Name>APPLICATION_BUCKET_NAME_test</Name><CreationDate>2011-01-20T21:42:56.000Z</CreationDate></Bucket></Buckets></ListAllMyBucketsResult>
endstring
FakeWeb.register_uri(:get, base_path, :body => body)

When "I attach the file \"#{file_path}\" to \"#{field}\""
end


The XML above provides Dragonfly with info about existing buckets in S3. This will ensure Dragonfly does not attempt to create the application bucket via a remote call. Make sure to replace APPLICATION_BUCKET_NAME_test with the right name for your test environment.

Finally, use that step in your Cucumber feature files:


When I attach the image "features/support/sample_image.jpg" to "Logo"


That is assuming of course that you have a file called sample_image.jpg nested under your Cucumber support directory.

Enjoy reaping the benefits of S3 usage with Dragonfly and test-driving it with Cucumber.

p.s. Let me know in comments if I missed a detail or if you have any questions.

Friday, January 07, 2011

How I Learned To Apply Design Patterns

Video has been posted for my Obtiva Lunch GeekFest talk this week:


How I Learned to Apply Design Patterns Obtiva Geekfest from Obtiva on Vimeo.


Here are the slides (with style change and some revisions): How I Learned To Apply Design Patterns


I would like to emphasize a few points that came up during the presentation from the audience:

  • Corey Haines brought up the point that you can benefit from thinking about Design Patterns even if you do no implement them to the tee per the Gang of Four implementation (e.g. double dispatch for Visitor).
  • Tyler Jennings brought up the point that you may sometimes need to split model responsibilities into a separate model responsible for performing the work, such as an OrderTransfer object for an Order. It becomes responsible for transaction-ability around product transfer between two orders.
  • Corey Haines mentioned that not all developers tend to think of which Objects to assign responsibilities to up-front.

One thing that got left out of the presentation is explaining how to choose variations of a design pattern, such as State vs Strategy or Abstract Factory vs Factory Method depending on the situation. That leaves me room for a future blog post/presentation. :)

In the meantime, comments and questions are greatly encouraged.

Saturday, January 01, 2011

Why Blog?

With the new year, it is good to re-evaluate certain habits to see if they still offer value, and one habit a I would like to re-evaluate here is why I blog:
- Organize my thoughts and opinions
- Solidify my knowledge
- Bookmark my learning (virtual breadcrumb)
- Validate my ideas
- Provide others with valuable lessons
- Connect with the community

A lot of developers are intimidated by the idea of blogging due to different reasons, such as:
- Do not have enough value to contribute
- Cannot write well enough to impress (I am not Bob Martin or David Heinemeier Hansson)
- Very time consuming

Actually though, everybody brings a different perspective and in a way, it is selfish to hold back on sharing your experience when others could have benefited from the lessons you learned.

About writing well, it is a learn-able skill, and in the Internet age where expressions like BTW and IMHO are common, it really does not matter as long as you get the idea across.

Finally, regarding time spent, you can always limit the size of your blog posts or break longer blog posts into multiple parts, which as a side effect builds up more anticipation for your blog posts.

I did not start blogging by writing an amazing article on software architecture or anything like that. I simply mentioned a good science fiction read, and here is my first blog post to prove it: http://andymaleh.blogspot.com/2006/11/plunge-into-blogging-world.html

Now if you have never blogged before, go write your first blog post now! It only takes 15 minutes or less and puts on you on a great path for sharing, organizing, and expanding your knowledge.