Off the Grid
Greg Osuri

I'm a hacker and an early stage investor interested in solving common problems in the simplest way possible.


I'm also the creator of Sociaholic.com - A better way to post tweets to your facebook

   

Search

June 19th, 7:41pm 0 comments

Simplest way to assign attribute values from constructor (initializer)

Ever wondered how you can assign attribute values for a ruby class directly from initializer with less code? check out the gist below.

Filed under metaprogramming ruby
May 4th, 8:56pm 2 comments

Powerful Twitter API Wrapper in less than 50 lines using Ruby Metaprogramming

I've been long fascinated about active record dynamic finders (find_by_) and wanted to write some thing similarly elegant, this twitter client uses ruby metaprogramming to dynamically generate objects and methods and adds simpler and easy to user methods for Twitter REST API

For. e.g., the REST method 'user/show' at http://api.twitter.com/1/users/lookup.json can be invoked simply by calling Twitter.new("user","pass").user.show(:screen_name => "gregosuri")

 

Some explanation of the code:

The program is constructed very similarly to active record dynamic finders, at the core it overrides object's method_missing and dynamically constructs the missing methods, Jay Fields has an excellent blog post that explains this technique.

For e.g., in client.statuses.show(:id=>'1234') the client object (Twitter instance) does not have statuses object during initialization, when this is called, it invokes the method_missing of Twitter class, and since this method(statuses) does not have any arguments or ends with post/get, method_missing will return 'self', i.e., in our case the statuses object. The Proxy is used to buffer the methods, this is useful to construct the URL for later use.

Now, 'show' method is called on 'statuses', since this has arguments it get processed by doing a HTTP GET to Twitter API. Once we have response from the server, an instance of TwitterResponse is created, the construct method accepts a hash/array and converts them into attributes and methods by using object.instance_variable_set and object.send in the constructor

Hope this helps, please follow me on twitter and/or subscribe to this blog.

April 14th, 7:10pm 4 comments

Sort on any attribute for objects stored in an array using Ruby Metaprogramming

Update 1: You could use array.sort_by{|obj| block } to achieve the same functionality. Read further if you are interested in learning more about Metaprogramming. (Thanks to knowtheory)

Ruby Metaprogramming is incredibly powerful, there are lots of good material and books but most of them i came across lack practical examples. One problem I was trying to solve is to perform a Bubble sort on objects stored in Array on their attributes, I believe this is a very common problem and I was able to do it with ease using almighty META.

I strongly advise watching the video by Dave Thomas and understand Ruby Object model before reading further.

The Problem

I have 6 objects of Person type in an sporadically created Array, each of them have 2 attributes - Name and Line_no. We want to sort the array based on Person's line number.

Solution 

We decided to use Bubble sort, mainly because its a simple to understand and we want any object to be able to use this function with out much modification. For simplicity purposes, I'm sorting ascending only on Integers, also assuming all the objects in the array are of same type.

First thing, is extending the Array to house our method "sort_by_attrib!"



class Array 
  def sort_by_attrib!(attrib)
     ....
  end 
end


If you notice closely in the code below, the ruby "self" is used at multiple instances, while self can change depending on where its called. It always represents the current/default object.

Also notice the send method which lets you call a method on the object. In our case self[i].send("#{attrib}") will return the value of the instance variable name that has the value of attrib, in our case it returns "line_no". The rest is pretty much the logic to do a bubble sort.

Full Code:

Hope you enjoyed the article, I greatly appreciate your feedback and thought. Please subscribe and follow me on twitter for more incredible updates.

April 12th, 7:48pm 2 comments

Connecting to IBM DB2 (on a mainframe) using JRuby and Active Record (If you care)

I'm going to cut the bull crap about why JRuby is awesome and get to the point, I was trying to access an old IBM Mainframe for a batch program in JRuby and couldn't find any thing useful on the blogosphere, so I decided to share how I did it. It was pretty simple using the Active Record JDCB adapter 

Setup:

  • Mac OS 10.5
  • jruby 1.4.0 
  • ruby 1.8.6
  • activerecord (2.3.5) - gem
  • activerecord-jdbc-adapter (0.9.4, 0.9.1) - gem
  • rails (2.3.5) - gem

Step 1: Install and setup JRuby

Step 2: Install the necessary gems (rails and activerecord)

jruby -S gem install rails activerecord-jdbc-adapter

If you choose to avoid rails, you can install active record as standalone too.

Step 3: Install Drivers

Download the DB2 Type 4 JDBC Drivers and place them in the same directory as your program, you can find them in your DB2 installation. You will need the following:

  • db2jcc-9.1.jar
  • db2jcc_license_cisuz-1.0.0.jar

That's pretty much it, check out the code sample to get you started

Code: