Sunday, March 6, 2011

Ruby Expression at First Glance

I started to learn Ruby language over the weekend.

If you have a C-like syntax language background like me, planned to learn Ruby for years, but never get started (with a valid reason, I know :-) Something quick to share with you today: a short highlights of Ruby expression.

Every statement returns a value
  • Every statement is an expression. You can code something like this:
    a = b = 1  # => 1
    
    bar = "spam"
    foo = if bar == "spam"
            "great!"
          else
            "keep going"
          end
    p foo  # => "great!"
    
    defined? var                 # => nil
    var = var || "default value" # => "default value"
    
Using defined?
  • If var is not defined, defined? var returns nil. Otherwise, it returns the var description.
  • It's a handy tool when learning the language in irb. But just curious how it is used in production code..
Parallel assignment
  • Swapping values of two variables is easy, like Python
    a = 1
    b = 2
    a, b = b, a   # => a=2, b=1
    
  • Or you can perform neat stunts using splat (asterisk prefix)
    list = [1,2,3,4]
    
    first, *, sec_last, last = list
      # => first=1, sec_last=3, last=4
    
    first, *middle, last = list     
      # => first=1, middle=[2,3], last=4
    
    # more stunts..
    a, b, c, d = *(1..2), *[3, 4]  # => a=1, b=2, c=3, d=4
    
The Ruby Truth
  • Everything is true, except nil, false.
  • That means 0 and '' is evaluated to true! Beeee careful.
Conditions
  • You can use normal if..elsif..else..end or unless..end statements
  • or append if/unless to a statement, like Perl
    process(order) if order.valid?
    
No breaks in case statement
  • Great to see there is no breaks :)
  • Note that, when statement uses === operator (case equality) to perform matching.
    case command 
    when "debug"
      dump_debug_info
      dump_symbols 
    when /p\s+(\w+)/
      dump_variable($1) 
    when "quit", "exit"
      exit 
    else
      print "Illegal command: #{command}" 
    end
Looping
  • Ruby provides while..end and until..end, or you can append while/until to a statement:
    puts a += 1 until a == 100
  • We may use for..in..end and loop do..end to iterate through a list, but I believe many Rubyists prefer list.each{}.
Variable scoping
  • Block introduces new scope. Block is a chunk of codes enclosed within {..} or do..end. A few ground rules:
    1. New variable defined in a block is not visible outside the block.
    2. Variables exist before a block, can be accessed within the block (think closure).
    3. A block's parameter will shadow a variable outside the block with same name.
    Here's an example,
    defined? local  # => nil
    x = y = -1
    [1,2,3].each do |x|
      local = y = x
    end
    defined? local  # => nil
    p x             # => -1
    p y             # => 3
    
  • Built-in expressions such as if, unless, while, until, for do not use block. So they do not introduce new scope. As a result, new variables defined in a while loop, will continue to exist after the loop.

Learn Ruby?
My rubyist friend, Yasith recommended to start with this book: Programming Ruby. The latest edition Programming Ruby 1.9 is available on bookshelf.

Tuesday, February 22, 2011

Manage multiple Grails versions in development

In Grails development, it's not uncommon to maintain several projects with different Grails versions.

It's a PITA to switch between Grails versions during development. Because it requires GRAILS_HOME to be updated, to point to the correct Grails directory.


Rescue My Ass
I added 2 new bash commands to make my life easy:
  • grls - list all available installed versions.
  • gr <version> - set GRAILS_HOME to the specified version.

How to Use
Beech-Forkers-MacBook:~ huiming$ grls
1.1.2
1.3.2
1.3.4
1.3.6
Beech-Forkers-MacBook:~ huiming$ gr 1.3.2
Beech-Forkers-MacBook:~ huiming$ grails
Welcome to Grails 1.3.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/huiming/work/tools/grails

How I Implement
First, I keep all Grails installations under a same directory:
Beech-Forkers-MacBook:~ huiming$ ls -d1 work/tools/grails-*
work/tools/grails-1.1.2
work/tools/grails-1.3.2
work/tools/grails-1.3.4
work/tools/grails-1.3.6

Then, add the commands into my ~/.profile file:
TOOLS=~/work/tools

function gr {
  rm -f $TOOLS/grails && ln -s $TOOLS/grails-$1 $TOOLS/grails
}
alias grls="ls -d $TOOLS/grails-* | xargs basename | sed 's/grails-//g'"

export GRAILS_HOME=$TOOLS/grails
PATH=$GRAILS_HOME/bin:$PATH

Thanks to Jeffs, as the idea is largely based on his solution.

Sunday, February 20, 2011

A Day of Pomodoros

The essence of Pomodoro technique is to stay focus, one task at a time, and take a break.

I guess somehow, Franceso Cirillo, the guy who invented this technique, has figured out a 25 minute-timebox is short enough for people (at least for me ;-) to keep their focus, while long enough to actually produce something useful.

What timer I use?
I'm using Ugo's Pomodoro Desktop for Mac. It's still available for download.


Tips: Always show current task
I find it very useful to always show the current task description on the screen. That's where I look at, when my mind started to wandering away..


A day of pomodoros
So here's a day of my pomodoros learning Grails. Well, guess I can use it as timesheet log as well. Neat feature, thanks Ugo!

First Impression: Grails vs Flask

Try this Exercise
Give yourself 2-3 days, pick up a new web framework you never use before, and build a small blogging app. Well, that's how I got first introduced to these two frameworks: Flask and Grails.

With short time constraint, it forces me to be aware of which parts of a framework actually help (or hinder) a developer to make progress. (btw, thanks to Sooyoung who introduced me the exercise ;-)

Here's a couple of things I observed while using Flask and Grails:
(Disclaimer: the post is written solely based on my first-time experience messing with the frameworks in few days time, so take it easy :-)  


Source Folder Structure
  • Flask lets you decide the source folder structure. You can code everything in single .py file, or organize by modules. It took me couple hours just to re-organize my single .py file to a working module structure. Also, you have to worry about how to organize unit tests.
  • Grails manages all folder structures for you. It provides commands (grails create-*) to create source files for you (e.g. controllers, views, unit tests) and store them properly in separate folders. A big big time-saver! 


Domain Model
  • It's okay to live without domain models in Flask. You can use SQLite, and switch to SQLAlchemy when really need it.
  • Grails has a rich Model DSL. The DSL lets you define model fields, relationship between models, processing before/after persistence, and input validation rules in single Groovy class file. Pretty neat stuff. After that, you can use GORM dynamic methods to query records. Here's an example:
    class User {
        String username
        String password

        static hasMany = [entries: Entry]

        static constraints = {
            username(blank:false, size:3..12)
        }

        def beforeInsert = {
            password = password.encodeAsSHA256()
        }

     
    // GORM dynamic finder:
    // def user = User.findByUsernameAndPassword(
    //                   username,
    //                   password.encodeAsSHA256())

Controllers
  • Flask and Grails both provide common controller utility objects (e.g. session, request) and functions (e.g. render, redirect, forward). I guess it's pretty much a standard feature now across modern web frameworks.
  • URL routing in Flask is annotation-based (similar to JAX-RS), while Grails separates it out to a config file UrlMapping.groovy. Interestingly, this led me to design URL structure up-front in Flask, while Grails allows me to delay the decision until the end of development.


View
  • Flask uses Jinja2 templating engine. I like Jinja2 for two reasons. First, the syntax is clean. Second, it provides an elegant model to extend base template. It's pretty much same as how a class method overrides its parent method:
    // base.html
    <html>
    <head>
      {% block head %}
      <link rel="stylesheet" href="main.css"/>
      {% endblock %}
    </head>
    <body>
      {% block navbar %}
      <div id="navbar"> .. </div>
      {% endblock %}
    </body>
    </html>

    // login.html
    {% extends base.html %}
    {% block head %}
      {{ super() }}
      <link rel="stylesheet" href="login.css"/>
    {% endblock %}
    {% block navbar %}
      {# empty block to hide navbar #}
    {% endblock %}

  • Grails uses GSP + SiteMesh templating engine. The XML-based DSL is a bit less elegant. Took me quite a while to figure out how to render the same output as Jinja2:
    // base.gsp
    <html>
    <head>
      <link rel="stylesheet" href="main.css"/>
      <g:layoutHead />
    </head>
    <body>
      <g:pageProperty name="page.navbar"
         default="${render(template:'navbar')}"/>
    </body>
    </html>

    //_navbar.gsp
    <div id="navbar">..</div>

    //login.gsp
    <head>
      <link rel="stylesheet" href="login.css"/>
    </head>
    <content tag="navbar">
      <%-- empty block to hide navbar --%>
    </content>

Dev Tools
  • Flask and Grails both apply code changes automatically when source files modified during development. I think it's a must-have feature. It enables developers to code without restart web server manually to apply changes.
  • In addition, Grails comes with a set of dev tools, such as bootstrap test data, config files, grails console etc.

If using the framework in next project..
I would use Flask for prototyping, as I can quickly code the entire app in single python file and run it. However, for a complex web app, Flask requires extra efforts. In that case, I might consider to use Grails.  

Anyway, if using Flask in my next project, I would invest initial efforts to..
  • setup complete source folder structure,
  • add config files,
  • find a input validation framework,
  • a web security plugin,
  • and i18n support.
For Grails, I might look for a way to simplify its templating DSL (using taglib?), and try out some web security plugins.


Try out Flask or Grails?
Feeling itch? Here's the kick-start tutorials: