(mis)?use of method_missing

B

Ben Stephens

I've added a method_missing method to a Day class so that=20
Day.six_days_from_now
can be written as well as
Day.days_from_now(6)

Is this stupid?

It seemed like a good idea at the time, but now I'm dubious about the
benefits especially when you could write
Day.three_hundred_and_forty_five_days_from_now

Bne
 
D

Daniel Berger

Ben said:
I've added a method_missing method to a Day class so that
Day.six_days_from_now
can be written as well as
Day.days_from_now(6)

Is this stupid?

It seemed like a good idea at the time, but now I'm dubious about the
benefits especially when you could write
Day.three_hundred_and_forty_five_days_from_now

Bne

require "date"
Date.today + 6

Use .to_s and/or .strftime as desired.

Regards,

Dan
 
J

Jamis Buck

I've added a method_missing method to a Day class so that
Day.six_days_from_now
can be written as well as
Day.days_from_now(6)

Is this stupid?

It seemed like a good idea at the time, but now I'm dubious about the
benefits especially when you could write
Day.three_hundred_and_forty_five_days_from_now

Another option, add the "days_from_now" method to Numeric, so you can
write:

6.days_from_now
345.days_from_now

- Jamis
 
N

Nathan Smith

Hello all,

Is there a way to define the arrow keys to traverse the command
history in IRB? I could google it but to be honest I am not quite
sure what to search for =) Thanks

Nate
 
J

Jason Foreman

install the readline extension for ruby and it will just work.

what platform are you on?
 
B

Ben Stephens

Thanks Daniel, that should simplify some of my code.
Another option, add the "days_from_now" method to Numeric, so you can
write:
=20
6.days_from_now
345.days_from_now
=20
- Jamis

Ooh, I like that, thanks.

Ben
 
K

Kirk Haines

Ooh, I like that, thanks.

This sort of thing is very useful.

irb(main):004:0> a = 4.days.ago
=> Fri Jul 29 05:08:19 MDT 2005
irb(main):005:0> b = a.from_now(1.week)
=> Fri Aug 05 05:08:19 MDT 2005
irb(main):006:0> c = 2.weeks.since(b)
=> Fri Aug 19 05:08:19 MDT 2005

Another thing that I have found very useful is adding some simple methods to
Date and DateTime to support easy conversions between all three (Time,
DateTime, Date) and to support this same family of actions on all of them.

irb(main):015:0> a = 3.days.from_now.to_datetime
=> #<DateTime: 331234343/135,0,2299161>
irb(main):016:0> b = a.ago(1.week)
=> #<DateTime: 331233398/135,0,2299161>
irb(main):017:0> b.to_time
=> Fri Jul 29 05:25:20 MDT 2005
irb(main):018:0> b.to_date.to_s
=> "2005-07-29"
irb(main):019:0> b.last_month.to_s
=> "2005-06-29T05:25:20Z"
irb(main):020:0> b.last_month.to_time
=> Wed Jun 29 05:25:20 MDT 2005
irb(main):021:0> b.next_month.to_time
=> Mon Aug 29 05:25:20 MDT 2005

Makes working with dates and times a breeze.


Kirk Haines
 
K

Kero

6.days_from_now
I don't. What does an Integer have to know about times and dates?

irb(main):001:0> 3 + Time.now
TypeError: Time can't be coerced into Fixnum
from (irb):1:in `+'
from (irb):1
irb(main):002:0> Time.now + 3
=> Tue Aug 02 14:20:43 CEST 2005

This sort of thing is very useful.
irb(main):004:0> a = 4.days.ago
=> Fri Jul 29 05:08:19 MDT 2005

Minute = 60
Hour = 60 * Minute
Day = 24 * Hour
Week = 7 * Day

### Disadvantages:
# - Can't spell out month
# - need different constants in Time/Date, etc.
# but then, 3.days.from(Time.now) and 3.days.from(Date.today)
# is going to stink too, unless you introduce a Day or Duration class...

### Advantages:
# - no 'readable' methods polluting Integer namespace.

a = Time.now - 4*Days
irb(main):005:0> b = a.from_now(1.week)
=> Fri Aug 05 05:08:19 MDT 2005

b = a + Week
# I'm much shorter here and I don't have the confusing word "now" in the
# code.
irb(main):006:0> c = 2.weeks.since(b)
=> Fri Aug 19 05:08:19 MDT 2005

c = b + 2*Week

[snip]
irb(main):020:0> b.last_month.to_time
=> Wed Jun 29 05:25:20 MDT 2005
irb(main):021:0> b.next_month.to_time
=> Mon Aug 29 05:25:20 MDT 2005

please use "next" and "prev" (as well as "last" and "first" :p )
in pairs.

if anything, last_month should be a class method, like Time.now()

Bye,
Kero.
 
K

Kirk Haines

I don't. What does an Integer have to know about times and dates?

This is why I use it as an extension in specific cases. :) For me, sometimes
convenience wins over principle.
irb(main):001:0> 3 + Time.now
TypeError: Time can't be coerced into Fixnum
from (irb):1:in `+'
from (irb):1
irb(main):002:0> Time.now + 3
=> Tue Aug 02 14:20:43 CEST 2005

I can live with that. The value in redefining + and - isn't worth the cost in
that case.
# - need different constants in Time/Date, etc.
# but then, 3.days.from(Time.now) and 3.days.from(Date.today)
# is going to stink too, unless you introduce a Day or Duration class...

Why? 6.months.ago returns a Time.
Date.today.ago(6.months) returns a Date.

Is the objection that 3.days returns 259200? I can see that on one level,
because Date and DateTime work off of a different scale than Time, does.
Adding 10 to a DateTime is entirely different than adding 10 to a Time. But,
really, adding 3.days to each should work the same (in my library, though, it
currently does not).
### Advantages:
# - no 'readable' methods polluting Integer namespace.

True. But, again, this is an extension to be used when it's pragmatic, and
isn't intended to be part of the core.
a = Time.now - 4*Days


b = a + Week
# I'm much shorter here and I don't have the confusing word "now" in the
# code.

from_now is just an alias. I could also do:

b = a + 1.week

And, in fact, when I use these, that's how I do it, most of the time. Every
once in a while, from_now _reads_ better to me, for a specific use, though,
and since my goal is to make this code easy for _me_ to read and maintain,
I'll use it in those cases.
c = b + 2*Week

That works if b is a Time. With your constants, though, that fails if b is a
Date or DateTime, as you alluded to in your Disadvantages list.

irb(main):003:0> b = DateTime.now
=> #<DateTime: 211989753587396153/86400000000,-1/4,2299161>
irb(main):004:0> 2.weeks.since(b).to_time
=> Tue Aug 16 08:39:47 MDT 2005
please use "next" and "prev" (as well as "last" and "first" :p )
in pairs.

In my English vernacular, last month is the previous month, but yeah, one can
do:

a = Time.now.prev_month
if anything, last_month should be a class method, like Time.now()

Maybe. next_month and next_year and their ilk are just sugar to make the code
read a bit more easily, for me.

One of the places where I use this is in a web based calendar that a customer
uses to schedule her workshops and conferences. It shows her a view of three
months at a time, and for me it is convenient to just keep track of the
middle month and then refer to the following or previous months with
#next_month and #last_month.

Making next_month into a class method would be far less useful to me.


Thanks,

Kirk Haines
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,500
Latest member
ArianneJsb

Latest Threads

Top