read file with one line of code 01. Jul 2008
There are probably at least a have a dozen ways to print the contents of a file in Ruby, here I will present four ways of doing it.
The first method is rather verbose. Assign a file object and iterate on the file object with the each_line method and then close the file.
f = open('file.txt')
f.each_line do |line|
puts line
end
f.close
The second method still assigns a file object, but then uses the more compact readlines instance method and closes the file.
f = open('file.txt')
puts f.readlines
f.close
The third method uses block form to access the file and automatically close it.
open('file.txt') { |f| puts f.readlines }
The fourth method calls the class method readlines to wrap it all up in one statement.
puts File.readlines('file.txt')
the beauty of ruby 1.9 28. Jun 2008
Let’s say we have a string and three arrays
string = "672"
java = []
ruby18 = []
ruby19 = []
Now you want to convert the string to an array of integers. If you were writing Ruby in javastyle you would probably write something like
i=0
digits = string.split(//)
while i < digits.size do
java << digits[i].to_i
i+=1
end
but since we’re we’re doing Ruby in rubystyle it looks more like
string.split(//).each { |digit| ruby18 << digit.to_i }
which looks much nicer, but still not quite right, but with Ruby 1.9’s chars interator it gets even better.
string.chars { |digit| ruby19 << digit.to_i }
Goes down like butter, doesn’t it? Isn’t that how it always should have been? And the good thing is, there is lots of this good stuff in Ruby 1.9. Maybe in Ruby 2.0 there will even be a to_i method in the array class, but now I’m getting carried away.
ordered hashes in ruby 1.8 19. Jun 2008
Ruby 1.8 doesn’t offer builtin ordered hashes, but there are several libraries out there which extend or replace Ruby’s Hash class. Among them are Ruby/RBTree, Ara T. Howard’s orderedhash and Ruby Facets. All three of these offer a hashlike syntax, letting you do things like
ordered_hash = Library['a', 1, 'b' ,2]
resulting in
{'a'=>1, 'b'=>2}
Sadly all three of these libraries have poor documentation. The one with most bearable in my eyes is Ruby Facet’s Dictionary, which also has a RubyGem available, so let’s have a look at it.
$ sudo gem install facets
Successfully installed facets-2.4.1
1 gem installed
Installing ri documentation for facets-2.4.1...
Installing RDoc documentation for facets-2.4.1...
Ruby Facets is a rather large library, so you’ll want to require just the Dictionary class.
>> require 'rubygems'
>> require 'facets/dictionary'
Let’s make an ordered hash with five elements and print it out.
>> dictionary = Dictionary[*(1..10)]
>> dictionary.each {|k,v| puts "#{k}=>#{v}"}
1=>2
3=>4
5=>6
7=>8
9=>10
Works fine. Now for the bonus round. Dictionary can also be used as a sorted hash by calling the order_by or more conveniently the order_by_key method. Once called this method ensures that all previously and subsequently inserted keys will be in sorting order.
>> array = Array.new(10){rand(100)}
>> dictionary = Dictionary[*array]
=> {1=>49, 48=>97, 17=>66, 6=>70, 52=>77}
>> dictionary.order_by_key
>> dictionary.each {|k,v| puts "#{k}=>#{v}"}
1=>49
6=>70
17=>66
48=>97
52=>77
ordered hashes in ruby 1.9 19. Jun 2008
If you create a hash in Ruby 1.8 and then browse it with the each-iterator you get the keys delivered in abitrary order.
>> hash = {:a=>1, :b=>2, :c=>3,}
>> hash.each {|key,value| puts "#{key}=>#{value}"}
c=>3
b=>2
a=>1
This might be okay for some cases, but in other cases you might want the insertation order preserved. Well, good news in Ruby 1.9 this works.
>> hash = {:a=>1, :b=>2, :c=>3,}
>> hash.each {|key,value| puts "#{key}=>#{value}"}
a=>1
b=>2
c=>3
slow iterators in ruby 1.9 on mac 17. Jun 2008
If you ever wondered why your Ruby programs are not faster but much slower with Ruby 1.9 you might be using each or times iterators on large collections.
10000000.times {}
In fact if you do a benchmark,
require 'benchmark'
n = 10000000
Benchmark.bm do |x|
x.report { n.times {} }
end
you get stunning results.
$ ruby bench.rb
user system total real
0.720000 0.000000 0.720000 ( 0.721872)
$ ruby1.9 bench.rb
user system total real
16.670000 9.110000 25.780000 ( 25.923977)
When increasing the number of iterations by powers of ten it looks like the computational complexity of the times iterator is O(n) in Ruby 1.9. According to Antonio Cangiano this behaviour is specific to Mac OS X and does not appear on Linux.