Archive for February, 2008
I am no expert in Ruby, but overtime I have accumulated some thoughts that may help you in writing better Ruby code.
- Always create a directory hierarchy for your library/application. Such as:
|__ bin |__ lib |__ tests |__ yaml_specs
- If your project hierarchy is like above and you are writing an library not an application, don’t make the mistake of putting all your files in lib directory straightaway. Rather have a setup like:
Root |__ bin |__ lib |__ lib/packet.rb |__ lib/packet/other files go here
And use relative requires in “packet.rb” file, like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) require "packet/packet_parser" require "packet/packet_meta_pimp" require "packet/packet_core" require "packet/packet_master" require "packet/packet_connection" require "packet/packet_worker" PACKET_APP = File.expand_path'../' unless defined?(PACKET_APP) module Packet VERSION='0.1.4' end
It would be helpful in avoiding package name collisions that otherwise your users will report.
- Once chris2 mentioned on #ruby-lang, you shouldn’t be overly clever with test cases. Don’t try to be too DRY in your test cases.
- Write code that can be easilly tested. What the fuck that means? When I started with Ruby and was doing Network programming. I used to write methods like ughh, that always manipulated state through instance variables. I either used threads or EventMachine. One of the issues with EventMachine is, code written usually relies on state machine and hence it can be notoriously difficult to unit test, because most of the time your methods are working according to the state of instance of variables. That was bad. Try to write code in more functional way, where methods take some parameters and return some values based on arguments. You should minimize methods with side effects as much as possible. This will make your code more readable and easily testable
- Read code of some good libraries, such as Ramaze , Rake, standard library.
- Use FastRi rather than Ri. If possible, generate your set of documentation using rdoc on Ruby source code. I spend time just looking through methods, classes just for fun. However, I don’t like the default default RDoc template, use Jamis RDoc template, if you like Rails documentation. Often for gems installed on your machine, you can use gem server or gem_server to view their documentation.
- #ruby-lang on freenode is generally a good place to shoot general Ruby questions. Be polite, don’t repeat and you will get your answers
- Avoid monkey patching core classes if your code is a library and will go with third party code.
If you are not writing a library and rather an executable application. Then, have a separate file that loads/requires required libraries and does some basic stuff. For example, I have a boot.rb in my Comet server that looks like:
1 2 3 4 5 6 7 | require "rubygems" require "eventmachine" require "buftok" require "sequel/mysql" PUSH_SERVER_PATH = File.expand_path(File.join(File.dirname(__FILE__),'..')) ["lib","channels"].each {|x| $:.unshift(File.join(PUSH_SERVER_PATH,x)) } require "push_server" |
Why? Because such a file can come handy when you are writing test_helper for your applications. There, you can simply require above boot.rb, so as you don’t have to copy stuff back and forth if your required libs change.
I am experiencing weird issue on my Notebook running Ubuntu Gutsy. Often, I will loose wireless connection and network manager will attempt to reconnect, but in stead of properly reconnecting to wireless router it just hangs. Whats more weird is, after this, I am unable to start any X application with few exceptions.
I have reported the bug here . Many have reported similar problems and I am waiting for a fix. However temporary workaround seems to be, to run
$ network-admin --sm-diable
and reset the network connections. Also, you can try deleting the /tmp/.ICE-Unix directory and files.
- Best place for BackgrounDRb documentation is the README file that comes with the plugin. Read it thoroughly before going anywhere else for documentation.
- When passing arguments from Rails to BackgrounDRb workers, don’t pass huge ActiveRecord objects. Its asking for trouble. You can easily circumvent the situation by passing id of AR objects.
- Its always a good idea to run trunk version rather than older tag releases.
- To debug backgroundrb problems. Its always a good idea to start bdrb in foreground mode by skipping ’start’ argument while starting the bdrb server. After that, you should fire rails console and try invoking bdrb tasks from rails console and find out whats happening. John Yerhot has posted an excellent write up about this, here
- Whenever you update the plugin code from svn, don’t forget to remove old backgroundrb script and run :
rake backgroundrb:setup
- When deploying the plugin in production, please change backgroundrb.yml, so as production environment is loaded in backgroundrb server. You should avoid keeping backgroundrb.yml file in svn. Rather, you should have a cap task that generates backgroundrb.yml on production servers.
- When you are processing too many tasks from rails, you should use inbuilt thread pool, rather than firing new workers
- BackgrounDRb needs Ruby >= 1.8.5
- When you are starting a worker using
MiddleMan.new_worker()
from rails and using a job_key to start the worker ( You must use unique job keys anyways, if you want more than one instance of same worker running at the same time ), you must always access that instance of worker with same job key. Thats all MiddleMan methods that will invoke a method on that instance of worker must carry job_key as a parameter. For example:
1 2
session[:job_key] = MiddleMan.new_worker(:worker => :fibonacci_worker, :job_key => 'the_key', :data => params[:input]) MiddleMan.send_request(:worker => :fibonacci_worker, :worker_method => :do_work, :data => params[:input],:job_key => session[:job_key])
Omitting the job_key in subsequent calls will be an error, if your worker is started with a job_key.
Its a no brainer in India that you should buy your favorite notebook from US if possible. The usual way is, Ask your friend, family , distance relative , beg them and if they are kind enough, you will get a good laptop in cheap bargain. But for most of us, its not possible.
So, I did a comparison between cost of same model notebooks in India and US and here are the results.
- Dell : I dunno about you, but I like XPS M1330. Its really an awesome notebook. Starting price in US for this model is $ 1000 and in India its about 52,000 ruppes. Assuming $1 = 40 Rs, you have a price parity of about 12,000 rupees and notebook is costlier by 300 dollars in India. Not bad I would say.
- Apple Macbook : I will leave Macbook air for you to figure. But simple white macbook costs around 59,000 Rs in India, while in US the same model costs 1100 dollars. Again assuming same currency conversion rates, macbook is costlier by 15,000 rupees or 350 dollars in India. Again, pretty good deal. The price difference used to be really high for Apple products, but Apple seem to have bridged the gap.
- Thinkpad T61: Well, Thinkpads are Thinkpads and generally T61 and X61 are one of the best notebooks out there.But wait a minute, entry level T61 costs a mind boggling 90,000 rupees (2250 dollars ) in India, while in US it costs 984 dollars. So If you are buying this notebook from India, you are paying 1266 dollars or about 51,000 rupees more. Apple is selling Macbook air for a price of 96,000 rupees in India and T61 is 90,000 rupees. Somebody should slap these bastards at Lenovo. It pisses me off badly. I can’t imagine, one single reason, why Thinkpad models are so overpriced in India.
- EEE PC: Again price parity is of about 6,000 rupees. EEE PC costs around 349 dollars in US and in India, it was launched at a price of 18,000 rupees.
Well, thats about it. I hope, Lenovo will learn and make thinkpads cheaper.
