Java vs Ruby

Runtime differences:

In Java the program always starts with a main method. Ruby program by default creates a main Object which is an instance of class class and then starts execution on it(weird!). It always starts reading from the first line of the file, there is no specific starting point.

So when you create a ruby test file HelloWorld.rb with below statement

puts "HelloWorld"

execute it in terminal with ruby HellowWorld.rb . Ruby interpreter creates main object and then starts to execute puts.(puts is an instance method from kernel module. These methods are called without a receiver).

To test this go to terminal irb and do the following.

ruby main object

Execution differences:

Java is a compiled language so the execution is a 2 step process. compile + run.

Ruby is an interpreting language.

Both Java compiler and Ruby interpreter are written in C.

Programatic differences:

Ruby is completely object oriented what does that mean from a java perspective ?

– In java we have primitive data types such as int, float etc along with Classes and Objects. In Ruby Integer, Float etc are also Classes inherited from Numeric class which intern inherited from Object class. here is a detailed image taken from which explains this.


So when you create an Integer in ruby you are creating a object for Integer class.

One more important ruby feature to discuss is duck typing.

Java is strictly or strongly typed language where we need to declare the type of variable.

Ruby has implicit and explicit type conversions.

Lets see what implicit conversion means.

duck typing

Ruby is loosely typed language where it tries to define the type of a variable implicitly as shown above. If it can not infer it it throws an error as below.

undefined local variable or method

Explicit conversion is kind of ruby’s way to type safety. I can try to convert into my expected type. see below.

ruby convert to string

Happy coding!


Difference between string and symbol in ruby

Ruby symbol and string does the same thing except symbol is more efficient in terms of memory and time.

As explained here

Symbol is the most basic Ruby object you can create. It’s just a name and an internal ID. Symbols are useful because a given symbol name refers to the same object throughout a Ruby program. Symbols are more efficient than strings. Two strings with the same contents are two different objects, but for any given name there is only one Symbol object. This can save both time and memory.

ruby string symbol

Therefore, when do we use a string versus a symbol?

  • If the contents (the sequence of characters) of the object are important, use a string
  • If the identity of the object is important, use a symbol.

We can change them to each other like this

puts “string”.to_sym.class # Symbol

puts :symbol.to_s.class    # String

Symbols are particularly useful when creating hashes and you want to have a distinction between keys and values.

Generate word document from google sheet

Generate a document out of google sheet is one of the tasks businesses wants when maintaining their data in spread sheets. It can be from PO, Bill of Lading, Invoice or what ever. Google makes it really easy for us to do this through App scripts. All  you need to have is a bit of java script knowledge.

Google does this magic by combining google api's and javascript run on it server (not everything in java script works here).

Lets assume we have a simple google sheet as below.

Lets say we want to generate a document as below.

There are 2 ways to do this.

  • Add a App script bound to the sheet (applies only to this script).

– Pros: We dont need to leave the sheet we are working on.

Can create a menu link to trigger script easily.

Write script by taking current selected range into consideration.

Business people loves it as they dont need to modify anything in the script.

– Cons: The script is applicable only to that sheet. There are ways to make it                                       available to other sheets also.

  • Create a independent App script and send sheet_id, rows to generate document as a variables.

– Pros:  It can be used for any sheet (by supplying the sheet id and row range info).

– Cons: You should know where the App script lives,  enter the the sheets id and                    rows range. It might be painful for the business people to enter all this low level                  details.

I will explain the first approach here(my favorite).

Create a document template:

Create a order summary template like this.

order summary template

Create a App script:

On the sheet menu go to `Tools` –> `Script Editor`

script editor

Give the project a name and replace the following script in it.

function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu(‘XYZ Menu’)
.addItem(‘Generate PO’, ‘createDcument’)

function createDcument() {
var activeSheet = SpreadsheetApp.getActiveSpreadsheet();
var activeRange = activeSheet.getActiveRange();
var row_data = activeRange.getDisplayValues();
var scriptProperties = PropertiesService.getScriptProperties();
var template_id = scriptProperties.getProperty(‘template_id’); // document template

/***Modify indexs if you the spread sheet columns shuffle **/
var attributes = {
bill_no: “0”,
vendor: “1” ,
date: “7” ,
description: “2” ,
length: “3” ,
width: “4”,
height: “5”,
weight: “6”
var documentId = DriveApp.getFileById(template_id).makeCopy().getId();
DriveApp.getFileById(documentId).setName(‘Purchase Order PO# ‘+ row_data[0][0]);
var body = DocumentApp.openById(documentId).getBody();

for (var prop in attributes) {
var index = attributes[prop];
var propValue = row_data[0][index];
propValue = propValue ? propValue : “”;
body.replaceText(‘##’+prop+’##’, propValue);

You can find the script here also.


I made the template_id as a script variable which can be set from File –> Project Properties so that you dont need to modify the script again.

script properties

Last thing you need to do is add Sheets API and Drive API by going into Resources –> Advanced Google services and also dont forget them to enable in Console.

advanced google services

phew! all the hard work is done sit back and refresh your sheet. You should be seeing the new menu XYZ Menu —> Generate PO

new menu from app script

Click on it (for first time it asks for permissions. grant it). Go to you template folder and you should see the generated document with the bill no included in the file name.

document generated

Hope this will save you sometime. Ping me with any concerns/ comments.


Rails migrations best practices

Avoid using Rails models in migration.


  1. Models might have some lifecycle callbacks which we dont want to be invoked in a migration.
  2. As we know what we are doing we dont want to deal with validations.
  3. Model names can change irrespective of db table.
  4. Try to use raw sql as close as possible.

Squash them after a period of time.


  1.  To my experience over a period of time these migration files are painful and useless.
  2. Every rake db:migrate might take a few seconds, or creating of a new database might take a few minutes when these files are big. Consider using tools like squasher.

Make them irreversible.


In Production it makes sense to have IrreversibleMigration as the code is tested in lower environments. If there is an issue try to fix it with a follow up migration.

Note: If there is a new developer in your team and setting up their environment. Let them do `rake db:schema:load` to get latest db copy.

Rails after_validation or before_save

I dont think i used after_validation ever as before_save(or similar callbacks like before_create or update) is the one which fits. Usually the flow is

Screen Shot 2018-08-03 at 1.45.57 PM

before_save seems to be the last step in the process and by the time it reaches there the record is valid. Like you wanted it to happen every time when validation is successful.

after_validation is called irrespective of the validation failed or not. I cant think of a scenario where you want to use it.

We cannot substitute after_validation for before_save as we can not guarantee that the record is always going to be valid.