Home > OS >  Case code in Ruby program not working with a passed value
Case code in Ruby program not working with a passed value

Time:10-21

Have written some test code for a program, trying to pass 2 values, a file and a number. The below doesn't work at all, but if I have something like puts "test" (outside the case) it works.

def read_album(music_file, number)
    puts number #(this does something)
    case number.to_i
    when(number > 1)
            puts "done"
    when(number < 2)
            puts "something"
    when(number == 3)
        puts "none of this inside case is working"
    end
end

def main()
    a_file = File.new("albums.txt", "r")
    print("Choose album id: ")
    choice_of_album = gets().to_i
    read_album(a_file, choice_of_album)
end

main()

CodePudding user response:

Your cases are not doing what you think. The expressions given to when are evaluated and the result will be compared to the case value using the case equality operator ===. An expression such as number > 1 will evaluate to either true or false. It makes no sense to compare this result to an integer in Ruby.

You should compare against the constants directly.

case number
when 1
  # handle 1
when 2
  # handle 2
when 3
  # handle 3
else
  # handle unknown case; error?
end

Note that other classes may override === to provide useful behavior. The Range and Regexp classes, for example, do this.

case number
when 1..3
  # handle 1, 2 and 3
end

case string
when /pattern/
  # handle pattern
end

Notably, the Proc class also does this!

def greater_than(n)
  proc { |x| x > n }
end

case number
when greater_than(2)
  # handle number > 2
end

CodePudding user response:

You need to drop the number.to_i from the case statement.

Or do something like

case number.to_i
    when 1..2 
        puts "foo"
    when 3..100
        puts "bar"
    else 
        puts "foobar"
    end
end

From the Ruby docs

Case statements consist of an optional condition, which is in the position of an argument to case, and zero or more when clauses. The first when clause to match the condition (or to evaluate to Boolean truth, if the condition is null) “wins”, and its code stanza is executed. The value of the case statement is the value of the successful when clause, or nil if there is no such clause.

Your version would evaluate to somehting like

if (number > 1) === number.to_i

and since you are comparing a number with a boolean expression this will not evaluate to true. If you had an else in the case statement this would have been called.

  • Related