Sleight of Hand for the Ruby Man
June 12th, 2008
Chad Humphries pointed me to this tasty bit of code. Since Ruby so graciously lets you open up classes anywhere, it’s nice to know where the right place to debug is. Simply put the following code into a globally accessible place (I just used .irbrc) and you will have the method available.
module Kernel
# which { some_object.some_method() } => ::
def where_is_this_defined(settings={}, &block)
settings[:debug] ||= false
settings[:educated_guess] ||= false
events = []
set_trace_func lambda { |event, file, line, id, binding, classname|
events << { :event => event, :file => file, :line => line, :id => id, :binding => binding, :classname => classname }
if settings[:debug]
puts "event => #{event}"
puts "file => #{file}"
puts "line => #{line}"
puts "id => #{id}"
puts "binding => #{binding}"
puts "classname => #{classname}"
puts ''
end
}
yield
set_trace_func(nil)
events.each do |event|
next unless event[:event] == 'call' or (event[:event] == 'return' and event[:classname].included_modules.include?(ActiveRecord::Associations))
return "#{event[:classname]} received message '#{event[:id]}', Line \##{event[:line]} of #{event[:file]}"
end
# def self.crazy_custom_finder
# return find(:all......)
# end
# return unless event == 'call' or (event == 'return' and classname.included_modules.include?(ActiveRecord::Associations))
# which_file = "Line \##{line} of #{file}"
if settings[:educated_guess] and events.size > 3
event = events[-3]
return "#{event[:classname]} received message '#{event[:id]}', Line \##{event[:line]} of #{event[:file]}"
end
return 'Unable to determine where method was defined.'
end
end
Once you have that you can simply open up script/console or irb and give it a whirl
>> where_is_this_defined {Streamlined.ui_for(:foo)}
=> "Streamlined received message 'ui_for', Line #6 of /Users/abedra/src/someapp/trunk/lib/extensions/streamlined/streamlined.rb"
This tells us that the ui_for method of streamlined is actually being called from an extension that the project made rather than the streamlined plugin itself. This would save you lots of time trying to debug the wrong method! Give it a try.
Rails on OpenBSD 4.3
June 7th, 2008
OpenBSD released version 4.3 of their OS on May first. This version is especially exciting because there has been considerable effort made by the ports contributors to get the Rails stack up to date. This makes setting up a server with OpenBSD considerably easier than my last set of posts regading deploying with OpenBSD. A few things have changed, but the idea is the same, so I will run through a full stack setup from a scratch install. If you need information on installing OpenBSD there is a great tutorial that will get you started.
Post Install
You will be greeted with a vanilla install and not a whole lot to work with. Let’s get some basic sytem tools installed. We will use OpenBSD’s pkg_add tool to get us up and running quickly. The stack we will setup will include:
- Helpful system tools
- Ruby / Rails
- Thin
- MySQL
- nginx
Helpful System Tools
# build the locate database
% /usr/libexec/locate.updatedb
# setup pkg_add path for easy installs
% export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/4.3/packages/i386/
# install bash (optional)
% pkg_add -i bash
% chsh -s bash
# install other needed system tools. we use pkg_add with the -i
# flag for interactive mode. this way it will ask you what version
# of a specific software you want if there is more than one available.
% pkg_add -i curl nano subversion git
Ruby / Rails / Thin
% pkg_add -i ruby ruby-iconv ruby-gems
% gem update --system
% gem install rails thin
# if you want to use thin with sockets you will need to install
# eventmachine from source to get version 0.11
% gem install eventmachine --source http://code.macournoyer.com
MySQL
% pkg_add -i mysql-server
% mysql_install_db
# start mysql
% mysqld_safe &
Create the file /etc/rc.conf.local and place the following into it.
mysql="YES"
Now open up /etc/rc.local and add the following script just before the ending echo ”.”.
if [ X"${mysql}" == X"YES" -a -x /usr/local/bin/mysqld_safe ]; then
echo -n " mysqld"; /usr/local/bin/mysqld_safe --user=_mysql --log --open-files-limit=256 &
for i in 1 2 3 4 5 6; do
if [ -S /var/run/mysql/mysql.sock ]; then
break
else
sleep 1
echo -n "."
fi
done
fi
This will setup mysql to start when the system boots.
nginx
% pkg_add -i nginx
Then open up /etc/rc.local and add the following after your mysql entry.
if [ -x /usr/local/sbin/nginx ]; then
echo -n ' nginx'; /usr/local/sbin/nginx
fi
This will setup nginx to start when the system boots. I like to modify my nginx configs a little bit taking a little away from the debian linux apache2 and nginx configs.
% cd /etc/nginx
% mv nginx.conf nginx.conf.orig
% mkdir sites-available
% mkdir sites-enabled
% curl -O http://aaronbedra.com/nginx.conf
% cd sites-available
% curl -O http://aaronbedra.com/vhost
This will enable nginx to automagically load any vhost file that is in sites-enabled. We use the sites-available and sites-enabled directories and symlink from one to another. I prefer this, you don’t have to do this if you already have an nginx setup you like to use. Assuming you followed the above steps the only thing you have left to do is edit the vhost file and add your sites information. I would suggest renaming the vhost file to something a little more descriptive as well. Don’t forget to create the directory in /var/log/nginx/yoursite or nginx will fail to start. Once you have completed that you just need to symlink your new config into sites-enabled and restart nginx.
% ln -s /etc/nginx/sites-available/vhost /etc/nginx/sites-enabled/vhost
# start nginx
% nginx
# restart nginx
% kill -HUP `cat /var/run/nginx.pid`
Post Setup Notes
There is one small problem with eventmachine on OpenBSD. When thin intializes eventmachine at application boot time, it tries to use the wrong eventmachine library. You need to use the pure ruby version. An easy way to fix this is to add the following to your .profile
export EVENTMACHINE_LIBRARY="pure_ruby"
This will make eventmachine happy and thin able to run. The reason for choosing thin and nginx over the other implementations is because thin can connect to to nginx via sockets, and nginx is just plain easier to configure, not to mention faster. Obviously you can season this setup to taste if you prefer other stack implementations.
Surviving the Reboot
It’s good practice to have a thin config file that can start your application. Let’s take a look at how to configure thin for your app.
% mkdir /etc/thin
% thin config -C /etc/thin/your_config.yml -s2 -S /tmp/thin.sock
This will create a thin config file that will spawn to instances of thin (s2) and use sockets instead of ports. You can change the number of instances it spawns or where you want to put your sockets if you so desire. Now that you have a running system, you just need to add one more thing to make sure that your app starts if your server reboots. To make this work you need to do two things.
% ln -s /usr/local/bin/thin /usr/bin/thin
This will make sure thin is available at boot time. Next you need to add a line in etc/rc.local to start your app. Add this after the other startup scripts you added previously.
echo -n " thin"; thin start -C /etc/thin/your_config.yml
Happy OpenBSD-ing!
Railsconf Talk
June 1st, 2008
Here are the slides from my railsconf talk. Thanks for all of you that showed up and gave support!


