Oh my God! Dave Thomas is an evil Cracker!
Yes, he is a malevolent cracker and I bet he has an evil world dominance plan!
So you want proof? Here! He has a wordlist!
http://pragdave.pragprog.com/data/wordlist.txt
:p
Faster Netbeans? Yes, it is posible… :)
Yeah NB can be slow sometime. So you say you had some megas of ram unused? Great. This trick is as old as … as something very old :-). I remember using this same thing to speed up quake on ms-dos.
- Uninstall Netbeans
- sudo mkdir /media/ramdisk
- sudo mount -t tmpfs none /media/ramdisk
- Then install netbeans to /media/ramdisk
That’s all
Off course, you will need a decent amount of ram. Netbeans uses like 95mb of disk for version 6.0.1 (linux)
I found that tmpfs writes its contents to the directory it was mounted to once you unmount it, so it should persist its contents between system boots! I just needed to update /etc/fstab with this line: “tmpfs /media/ramdisk tmpfs”
For Windoze, you should google for ramdisk support. I can’t get precise measures on the gain in performance, but I found that installing NB to ram really speeds things up. Now I should try to install the whole ruby interpreter in my ramdisk ….
UPDATE:
Amit Kumar Saha pointed out that tmpfs does not keep its contents to the disk on reboot. He is right. I manually unmounted the ram disk an it _did_ keep its contents to the disk, so I thought it was going to keep the contents also when booting. But when I did boot my pc, it didn’t work the same. To work around this, I did a tar package of my installation:
- cd /media/ramdisk
- tar cvvzf /home/emmanuel/tar/nb601.tar.gz netbeans-6.0.1/
Then added this line to my /etc/rc.local:
- tar xvvzf /home/emmanuel/tar/nb601.tar.gz -C /media/ramdisk
That surely worked on reboot. Off course I will have to create the tar again everytime I change something in the ramdisk.
PDF::Writer versus libharu2
Exploring two different libraries for pdf generation on ruby I found that they both have the same example (demo.rb) generating the same results (at least to my eyes :). One was the venerable PDF::Writer library, the other libharu2.
Here. Have some benchmarks on demo.rb:
#Rehearsal -------------------------------------------------------------------- #PDF Writer 100 times 18.984000 0.547000 19.531000 ( 19.616000) #Haru 2 100 times 0.235000 0.281000 0.516000 ( 0.517000) #PDF Writer saving file 100 times 18.531000 0.391000 18.922000 ( 19.836000) #Haru2 saving file 100 times 0.250000 0.375000 0.625000 ( 0.688000) #---------------------------------------------------------- total: 39.594000sec #user system total real #PDF Writer 100 times 18.500000 0.265000 18.765000 ( 18.866000) #Haru 2 100 times 0.156000 0.344000 0.500000 ( 0.500000) #PDF Writer saving file 100 times 18.703000 0.203000 18.906000 ( 19.336000) #Haru2 saving file 100 times 0.172000 0.407000 0.579000 ( 0.657000)
In this microbenchmark, libharu2 is almost 40 times faster than PDF::Writer !!! Because I think that libharu2 is very useful, I packaged it as a gem on rubyforge. Try it:
“sudo gem install hpdf“
Don’t forget to require ‘rubygems’ on your programs before requiring hpdf
HPDF TODO: Documentation, helpers (for example: no table drawer yet). I have only packaged the gem, didn’t add anything to it.
Delights of autoload in rails (or: Fixing class variables being cleared between requests)
For anyone not familiar with http://dev.rubyonrails.org/ticket/6730, I will tell you a story…. (p.s.: ticket was set to invalid, but explains very well the problem I was having)
I had this beautiful class written in a file on the /lib directory of my rails directory. That class stored some data in class variable. Something like this:
# /lib/nice_class.rb class NiceClass mattr_accessor :value end
# /config/environment.rb NiceClass.value= "Hi there" # << NiceClass auto-loaded by rails
Ok what happened is that in first request, the value was right, and if I displayed that value in a view, it showed me the message. On second request, I loosed the message! That was because of rails loading the class in every request. That didn’t happened on production mode.
Solution: In the class file, I put:
# Avoid rails loading this file in every request (in dev mode) unless Dependencies.load_once_paths.include? __FILE__ Dependencies.load_once_paths << __FILE__ end
Non-standard iterations over a collection: Getting prev and next element and sliding a window
Ruby way of iterating over a collection is great, we don’t need to know anything about the collection. In “standard” ruby, if an object responds to “each” message, we can be sure it is a collection that will yield each element inside it.
(1..10).each do |e| puts e end
Although this way of iterating prevents us from having to index the collection, it lacks the flexibility an index can give us. For example, getting prev, next or an arbitrary value from the collection. I would say that, if possible, we should change our algorithm to better suite the ruby way of iterating. But if we absolutely need more complex iteration, there are a couple of ways of accomplishing it.For modest needs we can rely in the goodness that the ‘enumerator‘ library supply. This library extends Enumerable objects with various methods. Two of them, each_slice and each_cons can be helpful for our needs. Lets qri these methods:
# e.each_slice(n) {...}
#Iterates the given block for each slice of elements.
require 'enumerator'
(1..10).each_slice(3) {|a| p a}
# [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]
# [10]
# e.each_cons(n) {...}
# Iterates the given block for each array of consecutive elements.
(1..10).each_cons(3) {|a| p a}
#[1, 2, 3]
#[2, 3, 4]
#[3, 4, 5]
#[4, 5, 6]
#[5, 6, 7]
#[6, 7, 8]
#[7, 8, 9]
#[8, 9, 10]
For ever finer grained iteration we can use Generators. With them we can yield arbitrary elements of a collection.
require 'generator'
def complex_iterator_for collection
prev= nil
Generator.new do |result|
collection.each_with_index do |current, idx|
nextv= collection[idx+1]
result.yield [prev, current, nextv]
prev= current
end
end
end
gen= complex_iterator_for((1..10).to_a)
while gen.next?
prev, current, nextv= gen.next
puts "# #{prev}, #{current}, #{nextv}"
end
# , 1, 2
# 1, 2, 3
# 2, 3, 4
# 3, 4, 5
# 4, 5, 6
# 5, 6, 7
# 6, 7, 8
# 7, 8, 9
# 8, 9, 10
# 9, 10,
Generators are not constrained to be used to iterate over collection, though. We could easily use them to create, for example, numerical series. Fibonacci, anyone?
require 'generator'
def fibonacci_gen till
a, b= 1, 1
Generator.new do |result|
0.upto(till) do
result.yield a
a, b = b, a + b
end
end
end
gen= fibonacci_gen(10)
while gen.next?
print "#{gen.next},"
end
# 1,1,2,3,5,8,13,21,34,55,89,
Perhaps this better explain the class name “Generator“.
Is interesting to note the analogies between Generators and Fibers (implemented on ruby 1.9). They work in a very similar way. Ruby 1.9 Fibers are not a library add-on though, but a very feature of the language, and should work much more efficiently than Generators.
This is an interesting Dave Thomas article about fibers.
Setting up rmagick (needs ImageMagick 6.3.x) on Ubuntu
I wanted to update rmagick to the latest version of the gem, so I ran “sudo gem install rmagick”. The version that was going to be installed was 2.1.0, and it needed ImageMagick lib 6.3.x.
I went ahead and downloadoaded 6.3.8 from ImageMagick site (couldn’t use apt-get this time, latest version on repositories I found was 6.2.4.5). I had a previous version of imagemagick laying on my system. So I ran:
- sudo apt-get remove imagemagick
- tar xvvzf ImageMagick.tar.gz
- cd ImageMagick
- ./configure –prefix=/usr
- make
- sudo make install
- sudo gem install rmagick
- sudo gem install rmagick -v 1.15.12 if you want rmagick v1 installed.
That’s all!
ActiveResource
I’m making my first contributions to rails. All of them deal with ActiveResource, a rails related library engineered to consume restful services.
It behaves more or less the same way as an ActiveRecord (even though it is NOT a replacement for ActiveRecords). With these in mind, I proposed these patches (not surprisingly some of them where already informed issues in the rails trac):
- Ticket 7308 Addition of update_attributes method
- Ticket 10537 Addition of new_record? method
- Ticket 9862 Modificate behavior for #new (initialize) , patch not provided yet (waiting for opinions)
If this patches where applied, one would be able to seamlessly replace an ActiveRecord with an ActiveResource in a scaffolded CRUD, restful web app (I used rails 2.0.2 and the scaffold provided with rspec 1.1.1 rspec_scaffold generator. Not sure if it works the same way as “scaffold” generator on rails).
Ubuntu gutsy problem number two: ruby script/console fails to start (readline)
Just for the record, number problem one was to set up mongrel_cluster on init.d.
Soooo. Now “ruby script/console” fails with a “require ‘readline’ failure” or something. The problem was that, for some reason, when i built the ruby interpreter (1.8.6) the readline extension was not built and installed. ruby’s readline extension comes with the standard ruby distribution. So, i did a:
- “locate readline” (probably you will need a “sudo updatedb” before, or better just look for the source code of your ruby interpreter where you know it is. You know that, right?
- Went to the directory where your ruby source code lives, subdirectory ext/readline. In my case: “cd ~/packages/ruby-1.8.6-p110/ext/readline“
- “ruby extconf.rb” –this one generates the makefile for the library
- “make“
- “sudo make install“.
In ubuntu you’ll problably need libreadline5 and libreadline5-dev _before_ running make:
“sudo apt-get install libreadline5 and libreadline5-dev“
Now “ruby script/console” should work.
mongrel_cluster does not work on restart of ubuntu gutsy?
I been struggling a couple of days to get my mongrel_cluster to run when system is restarted. As usual, this involves some configuration in the /etc/init.d directory. The proccess is pretty easy, and you can read it from the mongrel_cluster documentation. From the README of mongrel_cluster:
Supporting starting clusters on boot.
1. Create mongrel_cluster conf directory (/etc/mongrel_cluster).
3. Copy the init.d script from mongrel_cluster’s resouces directory to /etc/init.d.
4. chmod +x /etc/init.d/mongrel_cluster
5. Add to init.d startup. On ubuntu: “sudo update-rc.d mongrel_cluster defaults”
Now you should simlink the mongrel_cluster.yml of your app config directory to a file.yml on the /etc/mongrel_cluster directory. All this is all right and good, the problem is: when you restart the os, nothing happens! The solution: modifying the mongrel_cluster file on /etc/init.d. You should:
1) Add a path statement to mongrel_cluster file just above the CONF_DIR variable:
sudo vi /etc/init.d/mongrel_cluster
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local:/usr/local/sbin:/usr/local/bin
(Russ Brooks tip)
2) Create the proper user and user group… OR! just comment out the “USER=mongrel” line and the “chown $USER:$USER $PID_DIR”.
Thats it! Restart, and watch your mongrels be started by the /etc/init.d/mongrel_cluster script.
I should point out that I have found all this info in other places on the net. The problem is that every resource on the net has different pieces of the whole picture you need to get the thing up and running. The places I recommend for info are:
- http://articles.slicehost.com/2007/11/29/ubuntu-gutsy-mongrel-clusters-and-surviving-a-reboot
- also excellent documentation on http://wiki.slicehost.com/doku.php#ubuntu
- http://www.urbanpuddle.com/articles/2007/11/16/install-ruby-rails-on-gutsy-gibbon-nginx-versio
The last one has the “path” tip, the one that i was needing to get the thing to work.
Script de arranque nginx
http://pastie.caboo.se/117444
That’s all folks ![]()
