Monday, November 12, 2012

Simply Complex

Well .. I was reading through the Pragmatic Programmer's Guide and saw this piece of code.

def ExampleDate.once(*ids)
  for id in ids
    module_eval <<-"end_eval"
      alias_method :__#{id.to_i}__, #{id.inspect}
      def #{id.id2name}(*args, &block)
        def self.#{id.id2name}(*args, &block)
          @__#{id.to_i}__
        end
        @__#{id.to_i}__ = __#{id.to_i}__(*args, &block)
      end
    end_eval
  end
end

The guide said "Note that this redefinition uses the fact that methods may contain nested singleton method definitions, a clever trick." ..

Essentially the problem is to check if the value exists for the a variable. If not then do some calculations and set the instance variable. Then return that variable for all further calls to the instance method.

This variation does something unique.

First it makes an alias for the method which checks the if .. else. It redefines the name of the method to be __278626__ . The number signifies the identification number assigned for the symbol. This is done inside the module eval which adds stuff to the class which calls the once method like so.

once :abc, :def

The method is first declared with args and blocks. Then if you notice there is a self method declared too. The first fact is that we dont care whats in the instance method code block unless it is executed. For it to be executed, it should be called from an instance. Therefore when the method does get called, it is redefined in the scope of the object, ie the same method is redefined to return an instance variable. The call continues then to set the instance variable which is to be returned by the redefined method.

phew.

Friday, October 26, 2012

Semicolons in Javascript

I read this very interesting blog post today and kind of made me thinking .. 

Semicolons in JavaScript are optional - http://mislav.uniqpath.com/2010/05/semicolons/ by Mislav Marohnić (http://mislav.uniqpath.com/) 

Monday, September 17, 2012

Centralize a Tile based view

A project that I'm working on has a structure similar to what you seen in Pinterest. Except that the height of the Tiles do not vary as in Pinterest.

What happens essentially in Pinterest is that the Tiles are positioned absolutely. The Tiles are given left and top css properties and are positioned according with resize handlers.

But in this application, the height of the Tile is static. Therefore we could accomplish this with CSS and some javascript. One knows the width of the Tile (Look at Jquery's outerWidth) and the width of the window (Look at Jquery's width). One just has to set up a resize handler (Look at Jquery's resize) and do something similar to this.

var base = $('#content_wrapper'), window_width, post_width; 
if(base.length !== 0) { 
 window_width = $(window).width();
 post_width = $('.post:first').outerWidth(true); 
 if(window_width%post_width !== 0) {
  base.css({'width': window_width - (window_width%post_width)}); 
 } else { 
  base.css({'width': window_width}); 
 } 


$(window).resize(function() { 
 // Call the function here .. 
});

We will also need to call the function when the page loads too for the initial set up.

Wednesday, August 8, 2012

Compiling Ruby 1.9.2 with OS X 10.7

I had to setup a machine which ran 10.7 with Ruby 1.9.2 because the application ran on this version. It was a rails application of version 3.1.

I tried to get the machine set up with rbenv which went smooth.

I tried to do a

rbenv install 1.9.2-p180

Which did not go well at all.

I got errors like

/usr/bin/gcc-4.2 -dynamic -bundle -o ../../../.ext/x86_64-darwin11.3.0/racc/cparse.bundle cparse.o -L. -L../../.. -L/Users/jasonvdm/.rvm/usr/lib -L. -L/usr/local/lib -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -Wl,-flat_namespace  -lruby.1.9.1  -lpthread -ldl -lobjc 
compiling readline/usr/bin/gcc-4.2 -I. -I../../.ext/include/x86_64-darwin11.3.0 -I../.././include -I../.././ext/readline -DRUBY_EXTCONF_H=\"extconf.h\" -I/Users/jasonvdm/.rvm/usr/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE   -fno-common -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wshorten-64-to-32 -Wno-long-long  -fno-common -pipe  -o readline.o -c readline.c
readline.c: In function ‘username_completion_proc_call’:
readline.c:1386: error: ‘username_completion_function’ undeclared (first use in this function)
readline.c:1386: error: (Each undeclared identifier is reported only once
readline.c:1386: error: for each function it appears in.)
make[1]: *** [readline.o] Error 1
make: *** [mkmain.sh] Error 1

Which essential means that I needed to update the readline library to this error out of the way. I started out by downloading the readline version 6.1 manually and installing but that failed miserably.

curl -O ftp://ftp.gnu.org/gnu/readline/readline-6.1.tar.gz
tar xzvf readline-6.1.tar.gz
cd readline-6.1
./configure --prefix=/usr/local
make
sudo make install

Then I read this which saved me a lot of time. It essentially says to install readline via rvm. rvm was already installed in the system and readline got installed by the command.

rvm pkg install readline


Be sure to install the ruby version using the --with-readline-dir option. Like so

rvm reinstall 1.9.2 --with-readline-dir=$rvm_path/usr

Now when you try to install with this line, you might get it installed or you might get some errors like

ld: in /usr/local/lib/libiconv.2.dylib, missing required architecture x86_64 in file
collect2: ld returned 1 exit status
make[1]: *** [../../.ext/x86_64-darwin10.5.0/tcltklib.bundle] Error 1
make: *** [mkmain.sh] Error 1

Well, this means that you might have a wrong dylib file version on the machine.

The first this we need to look at now is whether we have XCode. If you have XCode and the version is 4.2 then you will have to check for this file in

/usr/lib/libiconv.2.dylib

Try to execute a file command on this

file /usr/lib/libiconv.2.dylib 
/usr/lib/libiconv.2.dylib: Mach-O universal binary with 3 architectures
/usr/lib/libiconv.2.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64 
/usr/lib/libiconv.2.dylib (for architecture i386): Mach-O dynamically linked shared library i386 
/usr/lib/libiconv.2.dylib (for architecture ppc7400): Mach-O dynamically linked shared library ppc

Find the x68_64 and you are in luck !

Just remove the old dylib and link the new one like so :

rm /usr/local/lib/libiconv.2.dylib
ln -s /usr/lib/libiconv.2.dylib /usr/local/lib/libiconv.2.dylib

Now running the rvm install works great !

Kudos !!!

References:
http://hello.keewooi.com/ruby-1-9-3-preview-1-available-now/
http://forums.pragprog.com/forums/148/topics/9975
http://geekyninja.blogspot.de/2010/12/installing-ruby-192-with-rvm.html
http://stackoverflow.com/questions/5426892/trouble-installing-ruby-1-9-2-with-rvm-mac-os-x
http://stackoverflow.com/questions/3703792/ld-symbols-not-found-when-linking
http://stackoverflow.com/questions/7962550/error-installing-ruby-1-9-3
https://rvm.io/packages/readline/
http://stackoverflow.com/questions/8675194/error-installing-1-9-3-with-rvm-on-lion

Friday, July 27, 2012

API accesses

Its great how far technology has advanced in terms of providing access. Now-a-days one gets all the APIs to access any online application. They even document it so precisely and accurately. And if one wants a wrapper for languages like Ruby, Python, Perl and PHP then that is readily available as well.

Well I'm going to shortly discuss about some Gems I have used to access these APIs.

The first Gem that I purely awesome is the 'omniauth' Gem. It has all the routines necessary to build add-ons for other Omniauth Plugins. You might need to read more about oauth to get an idea. I managed to use the plugins - omniauth-twitteromniauth-facebookomniauth-linkedin and omniauth-instagram with this Gem. And its so easy.

You will have to add an omniauth.rb file in the initializers for starters.


Rails.application.config.middleware.use OmniAuth::Builder do 
 provider :linkedin, LINKEDIN_CONFIG['api_key'], LINKEDIN_CONFIG['secret_key']   
 provider :twitter, TWITTER_CONFIG['consumer_key'], TWITTER_CONFIG['consumer_secret'] 
 provider :facebook, FACEBOOK_CONFIG['app_id'], FACEBOOK_CONFIG['secret'], :scope => FACEBOOK_CONFIG['scope'], :display => 'popup' 
 provider :instagram, INSTAGRAM_CONFIG['client_id'], INSTAGRAM_CONFIG['client_secret'], :scope => INSTAGRAM_CONFIG['scope'] 
end


It might be a good idea to insert these configuration files on deployment, rather than put them in the git.

The you will have to call something like

current_user.services.create!(
 :provider => auth['provider'], 
 :uid => auth['uid'], 
 :token => (auth['credentials']['token'] rescue nil), 
 :secret => (auth['credentials']['secret'] rescue nil))

Better add in lots of Exception handling.

This is the authorization part. The idea is generally at the end of the authentication, you will get a token which you should use for further requests to these services. To access the data from these services, one would have to use other Gems and then pass the auth_token (and auth_secret).

The gems used to access the data are :
fb_graph Gem for Facebook
twitter Gem for Twitter
linkedin Gem for Linked In
instagram Gem for Instagram

Try them out. You will love them.

Monday, July 9, 2012

The QR Hacker is a great tool ! I created mine here ..


Monday, July 2, 2012

FB Tab

My Father-in-law has this page on Facebook which is related to Astrology. He does a lot of work after his normal work to get stuff published to the site and let users have a good time reading the topics. He even answers them by email. Anyway, he wanted something set up on Facebook as a page and he sought my help. 

I wanted to test this out myself, so I thought I should see how it is done. I ultimately went on to use a third party app which did the page/tab creation. I was not happy with myself.

The previous week I had to do a similar thing and this time I had more resources to work with. These are some of my observations and pointers to set up a simple tab in FB.

The tab setup is not straightforward in FB. 

1. You will have to create an application which has the url (secure and non-secure) filled out. Make sure you select the 'Page Tab' option, fill in the Urls. Also remember to fill in the url in the Site URL field as well. 

2. Remember that your page should have a maximum width of 810px. The default width is 520px (I used 810px)

3. The height adjusts with itself. So I don't think you will have to worry about that.

4. Use this url to add the created application as a tab to your page 

http://www.facebook.com/dialog/pagetab?app_id=APP_ID&next=URL

I would suggest to use URL as http://www.facebook.com

5. Facebook posts a signed token to the URL you specified in the url field. It tries to use the non-secure one by default, but uses the secure one if FB was open as a secure connection.

6. Be careful if you intend to host the html file (end point HTML) in S3. Won't work. Simply because S3 treats POST requests as file uploads and gives out errors. As Facebook makes a POST request to the S3 URL you gave, you would probably see an unauthenticated message on the UI.

7. Better set up a server for the HTML and then add all the S3 stuff inside that !

That is pretty much it !

Monday, May 21, 2012

More Tips

It's nice to be learning new stuff. I'm just going to write line by line of some more stuff that I learned ..

Always use UTF-8 as the default charset in Mysql. 

I added this in my.cnf (/etc/)
[mysqld
default-character-set=utf8 
default-collation=utf8_general_ci 
character-set-server=utf8 
collation-server=utf8_general_ci 
init-connect='SET NAMES utf8' 
[client
default-character-set=utf8

If you are trying to sync between DBs, then take chunks of data.

Say you are trying to sync between DBs. And you want to do some transformation before sync (May be rename some columns). Then you would want to do a select query to get a subset of data (limit n) and then insert it in bulk using values (n values).

If there is a possibility of updates instead of inserts, then use the 'ON DUPLICATE KEY UPDATE' clause.
It's a good idea to update based on timestamps. What I did was that I touched a file everytime I do an update, so that the next time I know where I need to start from.

If a transaction fails because of Lock Errors write a retry routine in Code.

Lock might occur. Especially on DBs where there are a lot of reads/writes. So I would say try writing for x times and then raise an exception.

Optimize Active Admin if using with a DB with many records.

I have had this problem where the data in the table was HUGE and there were associations with another table with HUGE number of records. This caused the application to load very slowly and also made the writes to fail.

The fix that I made was to take out thos associations and write getters and setters instead of the associations. Some extra code, but make a HUGE difference to performance.

Use S3 when you want to store data.

The application had to generate reports and store them for future viewing. The flow in implementation is as follows


  1. User Creates Report
  2. He sets the report to execute on a specific time (he could also execute this report manually)
  3. On triggering of the report, a GeneratedReport is created and the job is pushed to delayed_job
  4. When the delayed_job gets to it, the report is executed and the result is written to a tmp file
  5. This tmp file is uploaded to S3 as a private file and a url is made with an expiration of months.

More to Come.


Thursday, April 12, 2012

ARN Radio 96.7 Dubai in VLC

I have been listening to the malayalam radio station from Dubai (96.7) for some now. Its pretty good with news, greta anchors and good songs. To add it in VLC just add the stream.

http://4103.live.streamtheworld.com/HITAAC

is the url for the stream. Save the playlist too so that you could load it the next time.

Enjoy !

Friday, March 23, 2012

Learning Start

I flew from Bangalore to Berlin on the 1st of March, the day my Visa starts. The weather was cold and gloomy. But I met some Mallus on the way and had some socializing. I asked them about the eating habits, where I could save money and stuff.

It took me 17 hours to reach Tegel, Berlin. After that I took a cab and went to the work place. A great bunch of people greeted me and gave me the laptop and other stuff. I stayed with John for some days before he left for his vacation. John even got me a sim that I have on my phone now !

I managed to get some paper works done. I have got my insurance and Burgeramt as of now. I am waiting for the Work Visa approval, apartment for rent, bank account etc ..

Anna took me to a small bar where they played music and the people who came in sand and played instruments. A bunch of people did a lot of YoYo tricks as well ...

Something like this one


Im at Gregory's apartment for now and am looking out for a place to stay before Reshma comes.\


Rails Dev is going great too ... I learned a lot of stuff too ...

Some of them are

Rspec
Rvm
guard
simplecov
factorygirl
pow and powder
gem based coding and development
databasecleaner
forgery
airbrake
relic
scalarium
activeadmin
devise
vagrant
markdown

Most of them I knew before and understood more ....

Exciting times !!!!

Sunday, January 15, 2012

FB Likes

I have been trying to get the Facebook Like to appear on an application. It was getting somewhat stressful because the Like would just not take the whole URL, but would take the base URL.


I started using the XFBML first because the way to integrate it is so nice. 


Add 


<html xmlns:fb="http://ogp.me/ns/fb#"> 


as the namespace and then use 


<fb:like href="http://google.com/" send="false" layout="button_count" width="450" show_faces="false"></fb:like>


Easy enough. The application used a lot of Ajax and therefore the these likes need some refreshing. To do this I used the Javascript method available


fb.xfbml.parse()


Function and it started working. But the likes were happening only for the base URL and not the href in the fb:like. This is when I saw the statement in the documentation which said 'The XFBML version defaults to the current page.' if href is used. 


urghh


I went on to use the iframe way so that I could get likes for the particular URL. It seems its important that the url end with '/' and only then Facebook identifies the absolute URL.