case statement and ranges

M

Mini Skirt

Hey, I want to do something like that:

case amount
when 25..50: 42
when 51..66: 78
when 90..123: 99
end

which works of course.

Now what I would like to have some other cases like when amount is lower
that 25, but with no minimum, or when it is higher that 123 ...
I could write something like:

case
when amount === (25..50): 42
when amount === (51..66): 78
when amount === (90..123): 99
when amount < 25: 100
when amount > 123: 200
else 0 # this would happen only when amount is in 67...90
end

But it doesn't feel that well ... since I am repeating my amount
variable all the time and this is precisely what the 'case something'
construct is about.

I cold also use some extremely high and extremely low values in ranges,
like (123..100000000) or (-10000000..25) to handle the other cases since
I know that in my use, it would be fine. But it does look quite
inelegant ....

thx
 
A

ara.t.howard

Hey, I want to do something like that:

case amount
when 25..50: 42
when 51..66: 78
when 90..123: 99
end

which works of course.

Now what I would like to have some other cases like when amount is
lower
that 25, but with no minimum, or when it is higher that 123 ...
I could write something like:

the basis of a solution:



cfp:~ > cat a.rb

case 42
when all:)a, :b, :c)
puts 'nope'

when any(42, 43, 44)
puts 'forty-two'
end


case 42
when any
puts 42
end


case 42.0
when any( 25 .. 50, any )
p 42.0
when 51 .. 66
when 90 .. 123
end

case 4.2
when any( 25 .. 50, any )
p 4.2
when 51 .. 66
when 90 .. 123
end


BEGIN {

class Pattern < ::Array
def initialize *elements
replace elements unless elements.empty?
end

def inspect
"#{ self.class.name }#{ super }"
end

class Any < Pattern
def === other
return true if empty?
any?{|element| element === other}
end
alias_method '==', '==='
end

class All < Pattern
def === other
return false if empty?
all?{|element| element === other}
end
alias_method '==', '==='
end
end

def all(*a, &b) Pattern::All.new(*a, &b) end
def any(*a, &b) Pattern::Any.new(*a, &b) end

}

cfp:~ > ruby a.rb
forty-two
42
42.0
4.2



a @ http://codeforpeople.com/
 
R

Ryan Davis

I agree that your second example doesn't feel right... I prefer
altering your original example:

case amount
when 25..50: 42
when 51..66: 78
when 90..123: 99
else amount < 25 ? 100 : 200
end
 
T

Todd Benson

I agree that your second example doesn't feel right... I prefer altering
your original example:

case amount
when 25..50: 42
when 51..66: 78
when 90..123: 99
else amount < 25 ? 100 : 200
end

Don't use this; it's just for fun...

my_number = 57
begin
[25, 51, 67, 90, 123].zip([100, 42, 78, 0, 99]).select {|a| a[1] if
my_number < a[0]}.first[1] rescue 200
end

Two things.

1. It's generally not good form to use a rescue for program logic

2. I'm surprised that no one saw the fundamental problem in using
ranges. We're looking at a line that has divisions, not pieces that
may or may not overlap. I suppose if you were clever, you could make
it work and have it behave almost the way you want it to.

I'd go with dividers instead of ranges. You could build your ranges
automagically with a list of the divisions, I suppose.

Even though at first glance it seems verbose, I do like Ara's
solution. And Ryan Davis' crack is really simple and succinct. Like
them both!

Todd
 
J

Joel VanderWerf

Mini said:
Hey, I want to do something like that:

case amount
when 25..50: 42
when 51..66: 78
when 90..123: 99
end

which works of course.

Now what I would like to have some other cases like when amount is lower
that 25, but with no minimum, or when it is higher that 123 ...
I could write something like:

case
when amount === (25..50): 42
when amount === (51..66): 78
when amount === (90..123): 99
when amount < 25: 100
when amount > 123: 200
else 0 # this would happen only when amount is in 67...90
end

But it doesn't feel that well ... since I am repeating my amount
variable all the time and this is precisely what the 'case something'
construct is about.

I cold also use some extremely high and extremely low values in ranges,
like (123..100000000) or (-10000000..25) to handle the other cases since
I know that in my use, it would be fine. But it does look quite
inelegant ....

thx

Big numbers are more elegant if they are big enough:

Infinity = 1/0.0
amount = 456
p case amount
when 25..50: 42
when 51..66: 78
when 90..123: 99
when -Infinity..25: 100
when 123..Infinity: 200
end
 
T

Todd Benson

If it goes in core it should really be

Infinity = 42/0.0

:)

Infinity + Infinity
=> Infinity
Infinity - Infinity
=> NaN
Infinity + Infinity - Infinity
=> Nan

Todd

Todd
 
J

Joel VanderWerf

Todd said:
Infinity + Infinity
=> Infinity
Infinity - Infinity
=> NaN
Infinity + Infinity - Infinity
=> Nan

That seems right, or at least that's what I get counting on my fingers.
 

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
473,770
Messages
2,569,586
Members
45,088
Latest member
JeremyMedl

Latest Threads

Top