Basic tech stuff

Programming and Linux administration

Archive for the ‘ruby’ Category

The Ruby module Enumeration is fun

Posted by Daniel Brahneborg on 2007 April 21

In a Ruby application I had a bunch of data in a hash table that I wanted to print in a special format. There were a couple of requirements:

  1. Some of the options should be ignored.
  2. The format should be “key:value”.
  3. The list should be sorted.
  4. The entries should be separated by a space.

Fortunately this sort of thing is dead easy in Ruby, because of all of the cool functions in the Enumeration module. By stacking them after each other, I got this:

KILL_LIST = [ 1, 42, 312 ]
def hash_for_print(hash_data)
  hash_data.
    reject {|key, value| KILL_LIST.include?(key)}.
    collect {|key,value| "%03d:%s" % [key, value]}.
    sort.
    join(" ")
end

No, it’s not something I’d use in the innermost loop of a realtime system. That’s irrelevant. The code is dead easy to understand and modify, and didn’t take much time to write. Besides, it scales linearly, which is quite important.

Andra bloggar om: , .

Posted in programming, ruby | Leave a Comment »

32 bit IP address to dotted notation in Ruby

Posted by Daniel Brahneborg on 2007 April 13

In one of our applications we store an IP address as a 32 bit integer. To show the value of this field it must be converted to normal dotted notation, and then back again to an integer to get stored in the database.

Going from dotted notation is easy:

require 'ipaddr'
IPAddr.new('1.2.3.4').to_i

Or, the “manual” version:

'1.2.3.4'.split('.').inject(0) {|total,value| (total << 8 ) + value.to_i}

I couldn’t find any examples of going from an integer to dotted notation, so I ended up with this:

address = 0x01020304
[24, 16, 8, 0].collect {|b| (address >> b) & 255}.join('.')

Andra bloggar om: , .

Posted in programming, ruby | 7 Comments »

Blowfish decryption in Ruby, revisited

Posted by Daniel Brahneborg on 2007 March 14

I wrote earlier about my struggles to get decryption to work in Ruby. Today I got it working, with good performance.

The solution was to write a Ruby extension in C, calling the Blowfish and AES functions in the OpenSSL library directly. Converting from Ruby types to C types and back is easy, so the process of figuring out how to do it, writing the code and tweaking it until the test suite passed again, took less than a day. Now time is measured in seconds again.

The thing that surprised me the most was when I changed decryption of file names and other short strings, to also use the C version. This gave yet another performance boost, cutting the time for the test suite from 5-6 seconds to less than 1. If nothing else, it shows that Ruby needs to get faster.

Andra bloggar om: , , .

Posted in encryption, programming, ruby | 10 Comments »

Conditional parameters in Ruby

Posted by Daniel Brahneborg on 2007 March 12

All cool Ruby hackers probably use this all the time, but I think it’s worth mentioning anyway.

I have a generic send_operation() function that takes a hash table of parameters to send. It’s used as the backend for the more user friendly things like login() etc. Some of the functions take a single, optional parameter. First I used the simple version:

args = nil
(args ||= {})[key] = value unless value.nil?
result = send_operation(op, args)

However, it can be made much nicer, using the fact that everything has a value. Combined with the “unless” modifier, I got a single line version that looks like this:

result = send_operation(op, ({ key=> value } unless value.nil?))

The parentheses around the “unless” construct is necessary, or Ruby gets a bit upset. Since there is an extensive unit test suite for all functions in all versions, it was easy to verify that it works correctly.


Andra bloggar om , .

Posted in programming, ruby | Leave a Comment »