Have you ever wonder how Rails and other ruby based frameworks include backtrace information whenever there is an exception? Me too. It is very well explained in the TRPL (The Ruby Programming Language). Check out this code:
SCRIPT_LINES__ = {__FILE__ => File.readlines(__FILE__)}
class Foo
def lala
code = []
(0..3).each { |i| code << SCRIPT_LINES__[__FILE__][__LINE__-(4-i)] }
raise ArgumentError,
"\n Problems here:\n #{"_" * 40}\n #{code} #{"_" * 40}\n ",
caller
end
def foo
lala
end
end
Foo.new.foo
If you run it (1.8.7), you'll get something like:
./foo.rb:14:in `foo': (ArgumentError) Problems here:
________________________________________
class Foo
def lala
code = []
(0..3).each { |i| code << SCRIPT_LINES__[__FILE__][__LINE__-(4-i)] }
________________________________________
from ./foo.rb:18
That is quite similar to the output you get in one of those frameworks we
were mentioning before. Yes, already, not as nicer. The secret is that
SCRIPT_LINES__ constant. There we hash our code file and then we use when
necessary. Here while raising an exception.
posted at: 13:47 | path: /ruby | permanent link to this entry
I came across these bits while going over ruby-talk:
class A < Struct.new(:a, :b)
def initialize(h)
# . (*self.class.members.map {|s| s.intern}
# self is A, but A extends Struct. .members return an array with
# all the names of the instance variables. We iterate over them with map
# and then we we call .intern to return the :symbol of it.
#
super *h.values_at(*self.class.members.map {|s| s.intern})
end
end
a = A.new(:a => 1, :b => 2)
p a
It is a very nice way to extend Struct so you instantiate the class by passing a Hash with attributes and values that you want to store in the struct.
That sort of inspired me to write this to help another developer:
# input.txt
# c,d,a,b
# 3,4,1,2
# Read first line and order the input
l1 = File.open("./input.txt", "r").read.split[1].split(',')
# Create a struct class to hold the stats per lane
line_stats = Struct.new(:c, :d, :a, :b)
# Instantiate a stat lines with the input data
l1_stats = line_stats.new(*l1)
# Display the contents of the struct
puts l1_stats.inspect
To get an idea about the domain of the problem. We want here to parse a
csv file, store the entries in memory and then call a perl script using
those values. There are a couple of things I would highlight about that
code. First of all, the nice way we can tell a ruby method that we
are sending the arguments in an array. Also, the Struct class fits right
in and avoid a bunch of lines of code.
posted at: 23:32 | path: /ruby | permanent link to this entry
Working with ruby 1.9 and 1.8 (from trunk)
I want to start playing with 1.9 but I want to keep 1.8 around. And also, I want to have the *latest* version of each branch. This is what I came up with:
$ pwd /Users/drio/ruby $ svn co http://svn.ruby-lang.org/repos/ruby/trunk ruby $ svn co http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8 $ cd ruby $ autoconf && ./configure --prefix=/Users/drio/local/ruby1.9 && make -j8 && make install $ cd ../ruby_1_8 $ autoconf && ./configure --prefix=/Users/drio/local/ruby1.8 && make -j8 && make install // add /Users/drio/local/ruby_local/bin to your path (change your user name of course)
Now, use this bash function:
funtion rversion() {
r_local="$HOME/local/ruby_local"
rm -rf $r_local && mkdir $r_local && cd $r_local
case "$1" in
'8')
version="ruby1.8"
l_dirs="bin lib share"
;;
'9')
version="ruby1.9"
l_dirs="bin include lib share"
;;
*)
echo "8 or 9 ?"
;;
esac
for d in $l_dirs
do
echo "linking $version/$d"
ln -s ../$version/$d .
done
cd - > /dev/null
}
Load that function and now, from the shell:
drio@lupita:~ $ rversion 8 linking ruby1.8/bin linking ruby1.8/lib linking ruby1.8/share drio@lupita:~ $ ruby --version ruby 1.8.7 (2008-09-03 revision 19079) [i386-darwin9.4.0] drio@lupita:~ $ rversion 9 linking ruby1.9/bin linking ruby1.9/include linking ruby1.9/lib linking ruby1.9/share drio@lupita:~ $ ruby --version ruby 1.9.0 (2008-09-07 revision 19210) [i386-darwin9.4.0]
Ruby long star conference, day 1
This year I am attending to the lone star lone star ruby conference in Austin, TX.
My first day was very interesting. I took a cap from the hotel to the conference center, then some crappy food for breakfast and then some training:
First one: Test Driven Development. I think we have already heart about this and hopefully we/you are already testing your code. Perhaps you are just writing your tests after writing your code. With this method, you write your test code first, then you code to make the test pass and so on.
I found interesting when they talk about rcov, a tool to calculate the test coverage of your code. Basically it shows you statistics about how many lines in your code haven't been covered by your tests.
The second talk I attended to was: the ins and outs of ruby IOs. The talk was also very
interesting but not what I expected. I missed more technical details about how ruby
interacts with the OS and how we can really improve, if possible, I/O against the filesystem.
Nonetheless quite interesting. James is a great speaker and his slides where impeccable,
full of interesting examples. I'll probably create another entry talking more about this
once I'll watch the slides again. The keynotes for the second day are starting now ... fun!
posted at: 09:09 | path: /ruby | permanent link to this entry