Chris Valentine
Chris Valentine

Reputation: 1637

Ruby extend Date class to add new method

I'm pretty new to Ruby and I'm trying to extend the Date class to add a function that will return the first sunday of the month. This is to help draw a monthly calendar. So say September begins on Saturday. Then i'd like this function to return August 26, as that is the date the calendar will need to draw first.

I have this working in irb as:

fs = Date.today - Date.today.mday + 1
fs = fs - fs.wday

So now i'm trying to extend the date class as

class Date
  def first_of_month
    return Date.new(self.year, self.month, 1)
  end

  def first_sunday_of_first_week
    return self.first_of_month - self.wday
  end
end

The first of the month method seems to work fine. The first sunday of the month doesnt. i'm thinking it has something to do with Date.new missing but no matter how I've tried to redo this it doesn't seem to work. I'm making a Sinatra app so I dont have the rails functions that do this.

The function here returns the first of the month for both methods and is not returning the first sunday of the month.

How do I correctly get this extended method to work? Thanks

UPDATE:

class Date
  def first_of_month
    return Date.new(self.year, self.month, 1)
  end

  def first_sunday_of_first_week
    first_of_month - first_of_month.wday
  end
end

This seems to work but is it correct or am i forcing more work than needed. Does this not created to Date.new's to return one?

Upvotes: 3

Views: 1613

Answers (1)

Lykos
Lykos

Reputation: 1029

You don't need the self.method and you don't need the return either, you can just write method to make it more concise. The problem is that you just subtract the wday of the current date, but you need to subtract the wday of the first day of the month

def first_sunday_of_first_week
  first_of_month - first_of_month.wday
end

That worked for me.

To your update: You could make it twice as efficient by avoiding the first_of_month method and doing it the following way instead:

def first_sunday_of_first_week
    first = Date.new(year, month, 1)
    first - first.wday
end

Your method calls the first_of_month method twice, hence the date gets created two times and in my version, only one instance is created. If performance is an issue, this would be slightly more efficient.

Upvotes: 2

Related Questions