hoodwink.d enhanced


Method Check: Date#succ #

by why in inspect

Date#succ has saved the day for me in calendaring operations. I was Duck Hunting and simply guessed it was there. (Someone should put together a Duck Typer’s Handbook that just contains the commonly reused method names and their presumed meanings.)

Basically, I want to rave about Ruby’s Date class, autonomous from Time. I had a table of rows which represented individual dates. I needed to take that table and build date ranges.

I’ll simplify by posing the problem as an event calendar.

 events = {}
 sqlq = "SELECT title, event_date FROM events ORDER BY event_date ASC" 
 db.query( sqlq ).each_hash do |event|
   date_e = Date.new( *event['event_date'].split('-').map { |n| n.to_i } )
   events[event['title']] ||= []
   last_e = events[event['title']].last
   if last_e
     if last_e[1].succ == date_e
       last_e[1] += 1
   events[event['title']] << [date_e] * 2

I’ll draw your attention to two lines. The last_e[1].succ and the last_e[1] += 1 lines. I’m building a Date range with a start and end date. So, last_e[1] represents the end date.

The line last_e[1].succ == date_e compares the day after the end date with the date from the database. If they match, then we know the date is the next date in the series.

The following line, last_e[1] += 1 adds a single day to the end date. Date math works really nicely like that. (Now, I’ll ask you how you prefer to add months and years.)

And, even better, Date objects inside of a Range.

 >> require 'date'
 >> D = proc { |*d| Date.new(*d) }
 >> (D[2004, 1, 1]..D[2004, 1, 12]).include? D[2004, 5, 6]
 => false
 >> (D[2004, 1, 1]..D[2004, 1, 12]).include? D[2004, 1, 6]
 => true
said on 24 Mar 2005 at 15:34

And while I’m here suggesting stuff:

The method String#rindex gets way too little attention. It’s wonderful. It’s the same as str[] but it actually starts at the end of the String and works its way from there on to the left.

Why is it wonderful? Let me tell you that James Edward Gray II (Yeah, that wonderful Ruby Quiz guy!) has found a very interesting use for it:

str "Hello. Ruby rocks. " * 50
while space_pos = str.rindex(" ", 80)
  f[space_pos, 1] = "\n" 

(I’m sort of paraphrasing him here as his code does lots of other funky stuff as well, but he came up with this.)

That code does line wrapping. It’s not complex any more.

And I’m pretty sure we can use this for converting 1000 to 1,000 and so on as well.

I hope I was able to show some of the reasons why you just have to report about this. I hope I didn’t fail too badly.

Oh, and let me thank you again for all the wonderful Ruby writing you do.

said on 25 Mar 2005 at 00:53

Requesting link to funky stuff, since I can’t seem to get that str replace to work properly… Tried (new ||= "") << "#{((chunk = str.slice!(0..pos)).nil? ? str : chunk)}\n" instead, but now I have a tmp var. tmp vars make me sad.

said on 25 Mar 2005 at 08:45

Yikes, I was typing f instead of str:

str = "Hello. Ruby rocks. " * 50
while space_pos = str.rindex(" ", 80)
  str[space_pos, 1] = "\n" 

And that is slightly oversimplified as well…

Ah, well, I’ll eventually be able to link directly to the real code, but not yet. Sorry.

said on 25 Mar 2005 at 09:51

Nah, not the f. I’m refering to str[] only happening for the first 75 due to space_pos not keeping up with the while. Hence the request to link to the real code, but if it’s not available, it’s not available.

said on 25 Mar 2005 at 18:48

Yeah, sorry for that. I can only link to it after the IORCC has closed, unfortunately, which is in five days.

said on 09 Aug 2005 at 15:32

(Someone should put together a Duck Typer’s >Handbook that just contains the commonly >reused method names and their presumed >meanings.)

Yes, it could be very convenient to have a list of methods and classes sorted by method instead of classes like the normal class hierarchies

Comments are closed for this entry.