ActiveSupport Option Hashes

A small blog item, for remembering this method…

When using a (normal) Hash in Ruby on Rails accessing an element with a symbol key or string key results in a different item.

Example
(Notice the use of a string and symbol to access a key)

normal = {'foo'=>"lish"}
normal[:foo] = 'bar'

results in the hash:

{"foo"=>"lish", :foo=>"bar"}

To solve this issue you can convert every Hash to HashWithInDifferentAccess

special = {'foo'=>'lish'}.with_indifferent_access
special[:foo] = 'bar'

Results in

{"foo"=>"bar"}
special.class => ActiveSupport::HashWithIndifferentAccess

that more like it :-)

“2008-03-30″.to_date.to_time.tomorrow == “2008-03-30″

I wrote a very nice routine which would iterate over a few days.
Today I found my loop never ending !?! And this is very scary because the routine is a background process that needs to iterate over the last x-days.

But there’s a problem when you’re living in The Netherlands and you have to use daylight savings.

Try this code:


>> "2008-03-30".to_date.to_time.tomorrow.to_date
=> Sun Mar 30

WTF !! 2008-03-30 => Tomorrow => 30 March 2008 ?!?

I indeed complained, that time was passing so quickly. But I didn’t mean to keep it stuck at 30 March!
Oh.. I’ts only my Rails Application…

How’s this possible?

>> "2008-03-30".to_date.to_time.tomorrow
=> Sun Mar 30 23:00:00 +0200 2008

At 30-03-2008 the clock has been set back for daylight savings. Well I assume rails simply adds 24 hours with the method tomorrow. And yesterday we had 25 hours.

More info about this bug: http://dev.rubyonrails.org/ticket/2353

My temporary solution is to add some hours to tomorrow.


>> tomorrow_time = "2008-03-30".to_date.to_time.tomorrow + 12*60*60
=> Mon Mar 31 11:00:00 +0200 2008
>> tomorrow_time.to_date
=> Mon, 31 Mar 2008

Sometimes I hate Ruby on Rails!

why don’t we collectively protest agianst the oppression of daylight saving time?
Well Tijn, I agree!

Ruby’s “Begin Rescue” and “Try and Catch”

Thanks to the book “Programming Language Pragmatics”
Programming Language Pragmatics
I’m beginning to appreciate Ruby’s different notation for exception handling.

A sample:

begin
  value = 7 / 0
rescue
  print "Something went wrong! This is an error"
end

The code above is to catch an exception. (In Java or C++ you would use try and catch)

Ruby also has got try and catch, but this isn’t used for exception handling. It is used for implementing “Multi Level Returns”.
A sample:

def search( name )
  # .. some fancy code here ..
  if filename.contains( name ) throw :found_it, filename
end

result = catch :found_it do
  search "one"
  search "two"
  search "three"
  false
end

In the sample above, result will be filled with the found filename. This can be
with the keyword “one”, “two” or “three”. If nothing is found result is filled with false. (the last value in the catch block)

I don’t think I need the catch construct very much, but it’s a nice feature!
Btw. I recommend the book “Programming Language Pragmatics”.

Ruby on Rails, ReXML Document serializing / deserializing

I’m storing an XML document into a database field. I’m having a lot of trouble loading and saving the same XML in the database.

Here’s a script/console session:

>> xml = REXML::Document.new("")   =>  ...   # strange response!!
>> xml.to_s   => " "   # seems ok!
>> xml.root.attributes['value'] = '<'
>> xml.to_s => ""  # fine by me, no problem...

>> # now for the scary part ;-)
>> xml2 = REXML::Document.new( xml.to_s )
>> xml2.to_s  => ""

The HORROR!

ReXML seems to escape items very nicely when setting values.
But it doesn’t unescape the values with REXML::Document.new( … )..

Current Progress:
* I found a method REXML::Document.write( ) which seems to do the same..

Today (24-8-2007) I’m a bit further, It seems it works correctly with the text content of elements:

>> xml = REXML::Document.new("")   =>  ...   # strange response!!
>> xml.to_s   => " "   # seems ok!
>> xml.root.attributes['value'] = '<'
>> xml.root.text = '>'
>> xml.to_s => ">"  # fine by me, no problem...

>> xml2 = REXML::Document.new( xml.to_s )
>> xml2.to_s  => ">"

Update 2 (24-8-2007) I found my Windows Ruby on Rails REXML (1.8.4) installation is working perfectly. It seems a bug in the FreeBSD version which is REXML (1.8.6).
I’m trying to submit a bug report to the REXML authors, but the server keeps timing out :(

I found the solution, there’s indeed a bug in REXML (1.8.6)

Change the code at line +/- 291 in text.rb: ( /usr/local/lib/ruby/1.8/rexml/text.rb )

#copy = copy.gsub( EREFERENCE, '&' )
copy = copy.gsub( "&", "&" )

To

copy = copy.gsub( EREFERENCE, '&' )
#copy = copy.gsub( "&", "&" )