2017-02-06 4 views
0

Я хочу заменить заявление case в рубине с Hash. Но Hash, кажется, сначала вызывает значение по умолчанию, когда я пытаюсь найти другие ключи в хэше.Заменить регистр с хешем в рубине

def perform_operation_one 
    puts 'Performing operation ONE' 
end 

def perform_operation_two 
    puts 'Performing operation TWO' 
end 

def exit_program 
    puts 'Program is exiting now' 
    exit(0) 
end 

def perform_operation(operation_code) 
    case operation_code 
    when 1 
     perform_operation_one 
    when 2 
     perform_operation_two 
    else 
     exit_program 
    end 
end 

Я заменил выше case заявление с Hash

def perform_operation(operation_code) 
    operations = Hash.new exit_program #Default value if no operation is present in operations corresponding to operation_code key 
    operations[1] = perform_operation_one 
    operations[2] = perform_operation_two 
    operations[operation_code] 
end 

Теперь, когда я выполняю следующее:

perform_operation(2) 

Ожидаемый результат:

Performing operation TWO 

Выходной ток:

Program is exiting now 
+0

Могу ли я спросить, почему вы хотите заменить инструкцию 'case'? Он выглядит намного чище ИМО (хотя я буду писать каждый «когда» в одной строке, т. Е. «Когда 1 затем выполняет_операцию_он»). – Stefan

ответ

3

Проблема эта линия:

operations = Hash.new exit_program 

оценивает exit_program право, когда эта строка кода будет достигнута.

Что вы пытаетесь сделать здесь, это передать метод как значение, которое вы можете сделать, но это не так просто, как сказать Javascript, где достаточно просто ввести имя метода. Помните, что в круглой скобке Ruby необязательны для вызовов методов, поэтому ваше значение по умолчанию заканчивается возвращаемым значением из exit_program (в этом случае это не определено после выхода программы).

Вы можете лямбда-FY ваши методы (пусть они передаются как значения) следующим образом:

def perform_operation(operation_code) 
    operations = Hash.new(-> { exit_program }) 
    operations[1] = -> { input_from_file } 
    operations[2] = -> { input_from_console } 
    operations[operation_code].call 
end 

Я в основном оборачивать каждый метод -> { } (анонимная функция/лямбда). .call есть, потому что вы указываете, что пришло время оценить лямбду (вызов метода).

Вместо использования -> { } вы можете также использовать method(:exit_program), method(:input_from_file) и т.д. Он преобразует в прок, но это в основном то же самое, вы все еще используете .call.

+1

Просто для удовольствия вы также можете использовать 'Hash.new {exit_program}' –

1

Во-первых, я думаю, что ваш case в порядке. Он читается и может быть менее подвержен ошибкам, чем решение с хешем.

С хэша, вы могли бы написать:

def perform_operation(operation_code) 
    operations = { 1 => :perform_operation_one, 2 => :perform_operation_two } 
    operations.default = :exit_program 
    send(operations[operation_code]) 
end 

Поскольку send не заботится о методе конфиденциальности, вы можете установить exit_program, perform_operation_{one,two} как частный. На самом деле они уже закрыты, если они определены в main.

 Смежные вопросы

  • Нет связанных вопросов^_^