Rational time durations
I needed to write a reporting script the other day that dealt with time durations. The script basically processed a series of log files determining the ‘start’ and ‘end’ times of certain events. Part of the report output needed to be the duration of each event. Calculating this using DateTime objects should have been as easy as this:
def duration
@end_datetime - @start_datetime
endAck, Instead of providing me with something intuitive, I got an object back of class Rational. A fraction of all things:
start = DateTime.parse('2/1/2008 10:35:00')
finish = DateTime.parse('2/1/2008 21:15:00')
duration = finish - start # => Rational(4, 9)Well, what the heck do I do with a fraction?
It turns out that Date has a class method called day_fraction_to_time() that takes a Rational and returns the number of hours, minutes, seconds and factions of a section. The beast in action:
start = DateTime.parse('2/1/2008 10:35:00')
finish = DateTime.parse('2/1/2008 21:15:00')
duration = finish - start
Date.day_fraction_to_time(duration) => [ 10, 40, 0, Rational(0, 1) ]Joy, this works, I now have my duration in hours minutes and seconds. The only conclusion I can draw regarding using Rational is that it can provide more accuracy than a Double or Float. In other words, it’s a more accurate representation of the percentage of a day since Rational( 1, 3 ) will not lose precision whereas ‘.3333333333’ is only as precise as the number of bytes a floating point number is stored as.
Posted in Ruby | no comments |
ieeemac.rb, why let python have all the fun?
I was a little bored tonight and thought I’d respond to a post over Happy Python with some code. Thanks for the inspiration Matt!
ruby>> require 'ieeemac'
# => true
ruby>> macs = Mac.find_macs `ifconfig -a`
# => [#<Mac:0x1357f40 @mac=["00", "16", "cb", "95", "13", "50"]>, #<Mac:0x1357f2c @mac=["00", "16", "cb", "ff", "fe", "5d"]>, #<Mac:0x1357d74 @mac=["00", "17", "f2", "41", "ec", "ec"]>, #<Mac:0x1357c20 @mac=["00", "50", "56", "c0", "00", "08"]>, #<Mac:0x1357ae0 @mac=["00", "50", "56", "c0", "00", "01"]>, #<Mac:0x135798c @mac=["00", "1c", "42", "00", "00", "00"]>, #<Mac:0x13577e8 @mac=["00", "1c", "42", "00", "00", "01"]>]
ruby>> macs[0].to_format :cisco
# => "0016.cb95.1350"
ruby>> macs[0].to_cisco
# => "0016.cb95.1350" Read the rest of this post for the full class.
Posted in Ruby | 2 comments |
On the fly field encryption/decryption
"ActsAsSecure adds an ability to store ActiveRecord model's fields encrypted in a DB. When a model is marked with acts_as_secure, the :binary type fields are recognized as needed to be stored encrypted. The plugin does before_save/after_save/after_find encryption/decryption thus making it transparent for a code using secured models.
The plugin supports a master key approach as well as individual records encryption keys. It does not contain any crypto provider but allows to plug in any external one as long as it supports encrypt/decrypt methods."
http://revolutiononrails.blogspot.com/2007/04/plugin-release-actsassecure.html
The site has some other goodies too.
Posted in Rails | no comments |
Message queues in ruby
Sometimes you run across neat and interesting libraries when you are reading up on something completely different. Case in point, via another blog, I stumbled on Reliable Messaging with Ruby. This looks to solve a problem I haven’t yet run into, but I know I’ll find a use for it in the future (maybe for a game I’m slowly working on, or a work project). As of today, there haven’t been any commits to the project for two years, but it’s entirely possible there are no bugs (except for the one I found below) and the author considers it feature complete.
Current feature list:
- Simple API.
- Transction processing.
- Disk-based and MySQL message stores.
- Best effort, repeated and once-only delivery semantics.
- Priority queues, message expiration, dead-letter queue.
- Message selectors.
- Local and remote queue managers using DRb.
New version of Net::SSH
Version 2 of Net::SSH and Net::SCP are on their way.
http://weblog.jamisbuck.org/2007/7/29/net-ssh-revisited
Using Active Record from outside of Rails
I’ve read a bunch of conflicting advice on how to use active record models defined in a Rails application from outside Rails.
The following is the result of experimenting with others’ advice plus my own digging around:
require 'rubygems'
require 'active_record'
require '/path/to/rails/config/environment'This should allow you to use your Rails models just like you would in a Rails controller:
#!/usr/local/bin/ruby
require 'rubygems'
require 'active_record'
require '/var/www/railsapp/config/environment'
m = MyModel.new
m.find_all.each { |row|
puts row.some_column
}
Treating gems as plugins
This is specific to rails 1.2 as I believe Edge Rails has this built in.
There’s been some amount of debate on various blogs on whether packaging up gems in your Rails application is a good choice. In my case, I decided that for me, the deployment convenience (a single application on a single server) far outweighs the maintenance aspects.
I found the ‘gems’ plugin over at techno-weenie.net that does exactly what I want with little effort. It’s a standard script/plugin install and installs a rake task (rake gems:freeze) which takes an argument of the gem you want to freeze. From the README
$ rake gems:freeze GEM=tzinfoinstalls the tzinfo gem in vendor/tzinfo-x.y.z (where x.y.z is the version of tzinfo that was frozen). If needed, you can freeze a specific gem version with:
$ rake gems:freeze GEM=tzinfo VERSION=0.1.2Posted in Rails | no comments |
Dot quad mask to CIDR
def dqtocidr( mask )
bitcount = 0
mask.split('.').each { |octet|
o = octet.to_i
bitcount += (o & 1) and (o >>= 1) until o == 0
}
return bitcount
end
irb(main):016:0> dqtocidr(‘128.0.0.0’) => 1
irb(main):017:0> dqtocidr(‘192.0.0.0’) => 2
irb(main):018:0> dqtocidr(‘224.0.0.0’) => 3
irb(main):019:0> dqtocidr(‘240.0.0.0’) => 4
irb(main):020:0> dqtocidr(‘248.0.0.0’) => 5
irb(main):021:0> dqtocidr(‘252.0.0.0’) => 6
irb(main):022:0> dqtocidr(‘254.0.0.0’) => 7
irb(main):023:0> dqtocidr(‘255.0.0.0’) => 8
Posted in Ruby | no comments |
Textmate plugin for rails
I’m trying to make more and better use out of TextMate for my rails development and have been bitching about having to find the code a rails backtrace points to when my apps blow up. Enter the footnotes plugin. This plugin will give you some links in the footer of your page that allow you to go directly to the controller, view, layout, stylesheets, javascripts, etc in TextMate. It also hyperlinks your rails backtraces so you can go direct to the line of code that’s erroring out.
Note the underlined lines in this backtrace - those are hyperlinks.
To install the plugin just run this command from your RAILS_ROOT.
script/plugin install http://macromates.com/svn/Bundles/trunk/Bundles/Ruby%20on%20Rails.tmbundle/Support/plugins/footnotesPosted in Rails | no comments |
Object destruction
Ruby does not provide programmer defined destruction methods. In C++ you can define a method that is messaged when the object instance is destroyed. This method can perform clean-up operations such as deleting temporary files.
Ruby, however, destroys objects dynamically during a scheduled garbage collection. This means that, during a run, it is impossible to know when an object instance will be destroyed. This fact combined with the lack of a destruction method can create headaches when there is a need to clean-up during object destruction.
Since there is no direct support for a destructor method, you must call a custom function, or more specific a proc object, when the garbage collector is about to destroy the object. As stated before it is unpredictable when this occurs.
Also if such a finalizer object has a reference to the orignal object, this may prevent the original object to get garbage collected.
Because of this problem, the finalize method below is a class method and not a instance method. So if you need to free resources for an object, like closing a socket or killing a spawned subprocess, you should do it explicitly with the ObjectSpace class.
class MyClass
def initialize
ObjectSpace.define_finalizer(self,
self.class.method(:finalize).to_proc)
end
def MyClass.finalize(id)
puts "Object #{id} dying at #{Time.new}"
end
end
# test code
3.times {
MyClass.new
}
ObjectSpace.garbage_collectPosted in Ruby | no comments |
Older posts: 1 2
