19 May 2011

A Rails developer’s impression of CoffeeScript – Part 1

CofeeScript posted by Shreya Bhatia

DHH has announced that Rails 3.1 will ship with CoffeeScript as default option for writing JavaScript.

All web apps use JavaScript (if you don’t, I don’t want to know you! ), and most Rails developers who are used to writing clean and pretty ruby code find it cumbersome to write JavaScript with all its curly braces and colons, (well, at least I did). Compared to that, CoffeeScript is wonderfully easy to understand and maintain. Lets hear it direct from the horse’s mouth -

  • CoffeeScript is neat language that provides an alternative syntax for writing JavaScript; the code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime.
  • Its integration with existing JavaScript libraries is seamless (like jQuery, Facebook JS SDK, Google API etc)
  • Works wonderfully in browsers that support JavaScript and JavaScript platforms like node.js
  • The code generated by CoffeeScript is syntactically correct and passes through JSLint without warnings.

A lot of writing about coffee. Let’s brew some -

var square;
square = function(x) {
   return x * x;
};

Equivalent CoffeeScript -

square = (x) -> x * x

It doesn’t need to explicitly declare the variable ’square’. The function body starts after ‘->’. We don’t need to use semicolons ; to terminate expressions. And we don’t need an explicit return statement, the last expression evaluated is returned.

How easy that makes a developer’s life! Understandably, Coffeescript has found acceptance in a lot of big rails projects. It is used by Github, 37 signals and more..

Getting Started

  * Lets get it working first – Check out the installation
  * The command-line version of coffee is available as a Node.js utility. The core compiler however, does not depend on Node, and can be run in any JavaScript environment, or in the browser.
  * Check out – the TextMate bundle for CoffeeScript


Why Ruby/Rails devs would love it or The similarity with familiar Ruby/Rails syntax


Variable declaration and expressions
You don’t need to use semicolons ; to terminate expressions, ending the line will do just as well, (although semicolons can still be used to fit multiple expressions onto a single line.) Also, no explicit variable declaration needed. Example -

company = "vinsol"

Functions
Functions are defined by an optional list of parameters in parentheses, an arrow, and the function body. The empty function looks like this: -> .CoffeeScript uses significant whitespace to delimit blocks of code – very haml-like. Last evaluated expression is returned (no need explicitly ‘return’ values). Almost everything can be wrapped in an anonymous function and used as an expression. Example -

square = (x) ->
   x * x

Default Arguments for functions
Functions may also have default values for arguments. We can override the default value by passing a non-null argument. You also have ruby-style string interpolation. Double-quoted strings can have interpolated values, using #{ … }

about_me = (profession = "developer") ->
    alert "I'm a #{profession}"

Function Calling
You don’t need to use parentheses to call a function if you’re passing arguments. The function call would wrap till the end of line for arguments.

console.log square 2 #=> console.log(square(2)) 

Significant Indendation
Instead of using curly braces { } to surround blocks of code in functions, if- statements, switch, and try/catch, use indentation.

if  x == 2
   alert "Value is 2!"
else
   alert "Value is not 2!"

Iterators
We can loop over arrays, ranges, hashes and objects using for operator in the postfix.

alert "I'm a #{profession}" for profession in ['developer', 'designer', 'tester']

Other goodies

Single line conditionals
It provides you with Post fix if-else conditionals. It compiles to ternary operator when possible and closure wrapping otherwise.

status = if couple then 'married' else 'single'
options or= defaults

Class inheritance using extends keyword
CoffeeScript gives a basic class structure,very much like ruby. It lets you add super class, assign prototype-properties and write the constructor.
Constructor functions begin with the name ‘constructor’. You are provided with concise constructors. Rather than doing this.length = length for class constructors, you can simply use the @ shorthand for this, (@length, @breadth) -> with an empty method body would form our constructor.

class Rectangle
  constructor: (@length, @breadth) ->

  area: ->
    alert "Area = " + (@length * @breadth)

class Square extends Rectangle

figure1 = new Rectangle 1,2
figure2 = new Square 1,1

figure1.area()
figure2.area()

Splats
Variable number of arguments get passed as an array in the last argument with ‘…’. Splats are used both for function definition as well as invocation.

gold = silver = rest = "unknown"

awardMedals = (first, second, others...) ->
  gold   = first
  silver = second
  rest   = others

contenders = [
  "Michael Phelps"
  "Liu Xiang"
  "Yao Ming"
  "Allyson Felix"
]
awardMedals contenders...
alert "Gold: " + gold
alert "Silver: " + silver
alert "The Field: " + rest

Heredocs
You can use single-quotes (otherwise – triple-quotes) for multi-line strings, leading indentation common to all lines will be stripped. Example -

 sample  = 'Lorem ipsum -
 lorem ipsum.. '

Literals in coffeescript for objects and arrays.
When each property is listed on its own line, the commas are optional. Objects may be created using indentation instead of explicit braces, similar to YAML.

 matrix = [
    1,0,1
    0,0,1
    1,1,0
]
en =
  form:
    company: "Vinsol"
    location: "Delhi"

Next Post will cover CoffeeScript in Rails 3 and Rails 3.1

Did you like this? Share it:
16 May 2011

Github2S3: Backup Github Repositories To Amazon S3

github posted by Akhil Bansal

Who doesn’t know GitHub now a days, its a service to host git repositories. We, at Vinsol, use GitHub extensively to host all(50+) of our git repositories. Although Github is an awesome service, we miss one feature a lot, which is ‘archiving a repository’ somewhere outside Github. This is somewhat similar to the ‘archiving a project’ in BaseCamp. Since every account on GitHub has a limit on number of private repositories, we wanted to have feature like archiving or backing up inactive repositories on S3 to comply with this limit.

As there is no such feature provided by GitHub, we wrote a ruby script last week to take backup of git repositories with all tags & branches. This ruby script reads a git repositories info from a YML file and upload compressed repository to S3.

You can download this ruby script and YML file from https://github.com/vinsol/github2s3. After downloading you need to make required changes in github_repos.yml file, which is basically adding your repositories and their clone urls. Also, you need to update your AWS ACCESS KEY & AWS SECRET ACCESS KEY and bucket name in github2s3.rb file.

# AWS S3 credentials

AWS_ACCESS_KEY_ID = "ACCESS_KEY"
AWS_SECRET_ACCESS_KEY = "SECRET_KEY"

# S3 bucket name to put dumps
S3_BUCKET = "github-backup"

Once you are done with the above required changes you can run this ruby script by “ruby github2s3.rb”. It will clone each of the repository mentioned in YML file, compress them and upload to S3.

Note:
- You must have permissions to clone the github repository
- You must have git and ruby installed with aws-s3, colorize gem
- You can also use command line arguments, ex: ruby github2s3.rb git@github.com:account/test_repo.git git@github.com:account/another_test_repo.git

Restore:
Restoring a repository from backup is very simple, just download the repository backup from s3, uncompress and run:

git push --mirror git@github.com:mycompany/my-new-repo.git

That’s it.

If you have any feedback or suggestions on this approach of archiving Github projects, please share your comments.

Did you like this? Share it:
09 May 2011

WebSockets with Cramp

websocket posted by waseem

Rails itself is not good at asynchronous event handling. And because of this it is bad at push techniques and also not a very good candidate for real time web applications. This problem exists in Rails because we can’t keep a bidirectional socket open between our client and a Rails application.

There are many solution that solve this problem. Node.js and Socket.io are some javascript based solutions. Whereas Faye, Goliath, async_sinatra and Cramp are some Ruby based solutions.

Cramp is an asynchronous framework running inside EventMachine loop. It means that while Cramp is communicating with a client over a connection, it can handle another connection with some other client simultaneously. And all of it is done by Cramp in a very scalable fashion. You should give it a shot for your next massive multiplayer online game.

Cramp implements solutions concerning real time web applications like long polling, streaming and WebSockets. In built support for WebSockets was introduced in version 0.9.

WebSockets are W3C specifications to create a bidirectional connection between a client and a server. This specification defines a fairly decent javascript API with which we can create a WebSocket connection between a client browser and a server. Following are a few javascript functions that let us open and communicate over a WebSocket connection from our browser to a server.

if (window.WebSocket) { // Check if browser supports WebSockets.
  ws = new WebSocket("ws://...");
}

ws.onopen();  // Called when a connection is established successfully with a server.

ws.onmessage();  // Called when a server writes on the open socket.

ws.onclose(); // Called when the opened connection is terminated successfully.

Cramp provides us a Cramp::Websocket class which lets us create our own Ruby class with WebSocket support. It also lets us define some methods or actions that are reflection of callback function provided by WebSocket API.

require 'cramp'

class WebsocketEnabledClass < Cramp::Websocket

  on_start  :user_connected           # Called when a connection is established successfully with the client.
  on_finish :user_left                      # Called when a connection with the client is terminated successfully.
  on_data   :user_said_something # Called when client writes on the open socket.

  def user_connected
    ...
  end

  def user_left
    ...
  end

  def user_said_something
     ...
  end
end

There is code of a small example chat application at github that you can check out. I will explain relevant portions of code right here.

require 'cramp'
require 'erubis'
require 'usher'

Cramp::Websocket.backend = :thin

module ChatRamp
  class HomeAction < Cramp::Action
    @@template = Erubis::Eruby.new(File.read('index.erb'))

    def start
      render @@template.result(binding)
      finish
    end
  end

  class SocketAction < Cramp::Websocket
    @@users = Set.new

    on_start :user_connected
    on_finish :user_left
    on_data :message_received

    def user_connected
      @@users << self
    end

    def user_left
      @@users.delete self
    end

    def message_received(data)
      @@users.each { |u| u.render data }
    end
  end
end

routes = Usher::Interface.for(:rack) do
  add('/').to(ChatRamp::HomeAction)
  add('/socket').to(ChatRamp::SocketAction)
end

Rack::Handler::Thin.run routes, :Port => 8080

Above is our main Cramp and WebSocket enabled Ruby script. Lets decode it line by line.

require 'cramp'
require 'erubis'
require 'usher'

Cramp::Websocket.backend = :thin

On first line, we require cramp for all the WebSocket goodies. Cramp itself does not yet have any rendering engine in itself. We use erubis to render our home page once a user tries to load it in his browser. On line three we require usher. It is a simple ruby gem that is used to define routes for rack applications. Finally we tell cramp to use thin as its backend server. Rainbows is other server that is currently supported by cramp.

module ChatRamp
  class HomeAction < Cramp::Action
    @@template = Erubis::Eruby.new(File.read('index.erb'))

    def start
      render @@template.result(binding)
      finish
    end
  end
  ...
end

We create a HomeAction class within ChatRamp namespace and make it inherit from Cramp::Action. Cramp::Action is very much like ActionController::Base of Rails. start action is executed when a user goes to home page of our application. It simply renders index.erb. There is much to Cramp::Action but we wont go into it in this article.

  class SocketAction < Cramp::Websocket
    @@users = Set.new

    on_start :user_connected
    on_finish :user_left
    on_data :message_received

    def user_connected
      @@users << self
    end

    def user_left
      @@users.delete self
    end

    def message_received(data)
      @@users.each { |u| u.render data }
    end
  end

Cramp::Websocket is the class where all the Websocket action is. We define some callback methods. user_connected simply puts the WebSocket connection created between our application and browser in @@users class variable. user_left simply removes that connection whenever this connection is terminated. And message_received loops through all current connections and writes data received to them. In other words it simply broadcasts the message to all the clients.

  routes = Usher::Interface.for(:rack) do
    add('/').to(ChatRamp::HomeAction)
    add('/socket').to(ChatRamp::SocketAction)
  end

  Rack::Handler::Thin.run routes, :Port => 8080

We use Usher to define routes for our application. And finally we start thin server to listen connections on port 8080.

Following is relevant javascript client side code in index.erb.

      if (!window.WebSocket)
        alert("WebSocket not supported by this browser");

      var room = {
        join: function(name) {
          this._username = name;
          var location   = 'ws://<%= request.host_with_port %>/socket'
           // document.location.toString().replace('http:','ws:');

          this._ws           = new WebSocket(location);
          this._ws.onopen    = this._onopen;
          this._ws.onmessage = this._onmessage;
          this._ws.onclose   = this._onclose;
        },

        _onopen: function() {
          $('join').className   = 'hidden';
          $('joined').className = '';
          $('phrase').focus();
          room._send(room._username, 'has joined!');
        },

        _onmessage: function(m) {
          if (m.data) {
            var c    = m.data.indexOf(':');
            var from = m.data.substring(0, c).replace('<', '&lt;').replace('>', '&gt;');
            var text = m.data.substring(c + 1).replace('<', '&lt;').replace('>', '&gt;');

            var chat = $('chat');
            var spanFrom = document.createElement('span');
            spanFrom.className = 'from';
            spanFrom.innerHTML = from + ':&nbsp;';
            var spanText = document.createElement('span');
            spanText.className = 'text';
            spanText.innerHTML = text;
            var lineBreak = document.createElement('br');
            chat.appendChild(spanFrom);
            chat.appendChild(spanText);
            chat.appendChild(lineBreak);
            chat.scrollTop = chat.scrollHeight - chat.clientHeight;
          }
        },

        _onclose: function(m) {
          this._ws = null;
          $('join').className = '';
          $('joined').className = 'hidden';
          $('username').focus();
          $('chat').innerHTML = '';
        }

      };

Lets try to understand it line by line.

      if (!window.WebSocket)
        alert("WebSocket not supported by this browser");

Here we test if user’s browser supports WebSockets. If it does not, we simply alert the user about it.

      var room = {
        join: function(name) {
          this._username = name;
          var location   = 'ws://<%= request.host_with_port %>/socket'
           // document.location.toString().replace('http:','ws:');

          this._ws           = new WebSocket(location);
          this._ws.onopen    = this._onopen;
          this._ws.onmessage = this._onmessage;
          this._ws.onclose   = this._onclose;
        },
       ...
    }
    ...

We create a room javascript object join function is called whenever a user clicks on “join” button on home page. It uses WebSocket API to create a new WebSocket instance that is tied to /socket end point in our application. onopen is called when the connection is successfully established between browser and server after a handshake. It simply updates some HTML fragments on our home page. onclose works on same lines however it is called when connection is terminated. onmessage is called whenever server pushes something to the browser. It simply updates the home page with message pushed by the server.

Following are some pointers that might be helpful exploring Cramp and WebSockets.

Did you like this? Share it:
21 May 2010

Meet Vinsol at RailsConf 2010

railsconf posted by kapil


Vinsol will be attending the RailsConf 2010 (June 7 – June 10).
Manik, Rishav and Gaurav will be there in Baltimore learning cool stuff and interacting with some cool rails developers. If you happen to be around, we would like to meet you! Drop us a comment, an e-mail , or catch Vinsol on Twitter.

Did you like this? Share it:
23 Apr 2010

Upgrading Restful Authentication Plugin for Rails 3

Rails 3 posted by kapil

Here at Vinsol, we love to be on cutting edge of Ruby on Rails.

When I tried to use restful authentication generator plugin for Rails 3 app, I got ‘Could not find generator authenticated’ error. Generator system in Rails3 is now replaced with Thor which is a scripting framework that replaces rake and sake. Rails 2.x.x finds generators in generators/ or rails_generators/ directory of a gem or a plugin, but the new Thor based system looks for lib/generators/ or lib/rails_generators/ directory.

I forked the original restful-authentication plugin and did the necessary changes to make it compatible with Rails 3.0.0.beta3. Updated code is available at http://github.com/Satish/restful-authentication and the original project page is here.

Comments welcome.

Did you like this? Share it:
Next Page »« Previous Page