I feel like this should be simple but i can't figure it out.
In a case statement, i know how to use ranges to compare against the
given variable. But how do i use < or > ? eg i want to do this:
age = 25
category = case age
when < 12 : "child"
when 13..17 : "minor"
when 18..24 : "young ad*lt"
when 25..49 : "ad*lt"
when 50..64 : "middle aged"
when > 65 : "senior"
else : "not an age"
end
(please don't anybody be offended by my age categories, i just made up
this example off the top of my head)
Anyway, the above doesn't work - syntax error.
Neither does this:
when age < 12 : "child"
the test doesn't pass, so if age is eg 10, i get nil back.
Can someone set me straight?
thanks
max
···
*******************************
postscript - it seems the word 'ad*lt* triggers the spam filter. hence
the odd wording above.
--
Posted via http://www.ruby-forum.com/.
In a case statement, i know how to use ranges to compare against the
given variable. But how do i use < or > ?
Simplest solution is to use a Range with extreme bounds, or use an if
statement (if age < 25 ...).
The long answer is to explain that
case foo
when bar
...
end
is syntactic sugar for
if bar === foo
...
end
So you can get whatever behaviour you like by creating an object which
responds to the === method.
class Bounds
def initialize(meth,val) @meth, @val = meth, val
end
def ===(other)
other.send(@meth, @val)
end
end
def is(meth,val)
Bounds.new(meth,val)
end
age = 70
case age
when is(:<,25)
puts "Youngster"
when is(:>,65)
puts "Oldie"
end
If you wanted this to be more efficient, you could define constants like
As the others pointed out, there's no easy way to do what you want to.
On the other hand, if you know the bounds of your inputs, your method
isn't bad ; I'd write :
category = case age
when 0...12 then "child"
when 12...18 then "minor"
when 18...25 then "young ad*lt"
when 25...50 then "ad*lt"
when 50...65 then "middle aged"
when 65...999 then "senior"
else "not an age"
end
Note that the use of : within if's and case's has been deprecated in
Ruby 1.9 and the next versions.
Fred
···
Le 2 juin 2009 à 11:12, Max Williams a écrit :
category = case age
when < 12 : "child"
when 13..17 : "minor"
when 18..24 : "young ad*lt"
when 25..49 : "ad*lt"
when 50..64 : "middle aged"
when > 65 : "senior"
else : "not an age"
end
--
Home, home again I like to be here when I can
When I come home cold and tired
It's good to warm my bones besides the fire
(Pink Floyd, Breathe Reprise)
In a case statement, i know how to use ranges to compare against the
given variable. But how do i use < or > ?
So you can get whatever behaviour you like by creating an object which
responds to the === method.
class Bounds
def initialize(meth,val) @meth, @val = meth, val
end
def ===(other)
other.send(@meth, @val)
end
end
def is(meth,val)
Bounds.new(meth,val)
end
age = 70
case age
when is(:<,25)
puts "Youngster"
when is(:>,65)
puts "Oldie"
end
Wow, that's a lot more complicated than i thought. I think for the sake
of ease and readability i'd stick with doing a more longwinded version,
like
category = case
when age < 12 : "child"
when (13..17).include? age : "minor"
when (18..24).include? age : "young ad*lt"
when (25..49).include? age : "ad*lt"
when (50..64).include? age : "middle aged"
when age > 65 : "senior"
else : "not an age"
end
thanks for your in-depth answer robert! i'll chew over that. but, in
terms of readability, i think my solution of not passing age into the
block and instead testing it on every line is fine.
Wow, that's a lot more complicated than i thought. I think for the sake
of ease and readability i'd stick with doing a more longwinded version,
like
category = case
when age < 12 : "child"
when (13..17).include? age : "minor"
when (18..24).include? age : "young ad*lt"
when (25..49).include? age : "ad*lt"
when (50..64).include? age : "middle aged"
when age > 65 : "senior"
else : "not an age"
end
thanks for the insight though!
If you want to allow for the possibility of fractional ages:
when (13...18).include? age
when (18...25).include? age
when (18...50).include? age
.. etc
That's an interesting idea.. I can see an opportunity for a great deal of
abuse there, as well.
It would certainly be cool to write my infinite loops like:
(0..Infinity).each {|d| ... }
Alex
···
On Tue, Jun 2, 2009 at 3:21 PM, Mark Thomas <mark@thomaszone.com> wrote:
On Jun 2, 9:32 am, Max Williams <toastkid.willi...@gmail.com> wrote:
> Clifford Heath wrote:
> > Brian Candler wrote:
> >> Simplest solution is to use a Range with extreme bounds,
>
> > ... such as a range that ends in Infinity:
>
> > 65..(1/0.0)
> > => 65..Infinity