Case statement and ranges

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

On Thu, 2008-08-14 at 07:21 +0900, Mini Skirt wrote:

else 0 # this would happen only when amount is in 67…90
end

If you use version 0.5 my ‘case’ gem:

require ‘rubygems’
require ‘case’

case amount
when (25…50): 42
when (51…66): 78
when (90…123): 99
when (Case::Cmp < 25): 100
when (Case::Cmp > 123): 200
else 0
end

-mental

On Aug 13, 2008, at 4:21 PM, Mini Skirt wrote:

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/

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

On Wed, Aug 13, 2008 at 6:59 PM, Ryan D. [email protected]
wrote:

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 D.’ crack is really simple and succinct. Like
them both!

Todd

Mini Skirt wrote:

Now what I would like to have some other cases like when amount is lower
end
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

I always throw this in my core_ext:

class Float
Infinity = 1.0/0.0
end

On Wed, Aug 13, 2008 at 9:34 PM, Joel VanderWerf
[email protected] wrote:

Infinity = 42/0.0

:slight_smile:

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

Todd

Todd

Infinity = 42/0.0
UniverseError: ‽‽‽
from (irb):2

elliottcable wrote:

I always throw this in my core_ext:

class Float
Infinity = 1.0/0.0
end

If it goes in core it should really be

Infinity = 42/0.0

:slight_smile:

Todd B. wrote:

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.