Ruby останавливает итерацию в блоке case, если возвращает true

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

У меня ниже, если блок:

   scoring = if match_invoice_number(resource)
              3
            elsif match_amount(resource) amp;amp; match_vendor(resource)
              2
            elsif match_vendor(resource)
              1
            else
              0
            end
 

который я заменяю на приведенный ниже регистр:

   def score(resource)
    case resource
    when match_invoice_number(resource) then 0
    when match_amount(resource) amp;amp; match_vendor(resource) then 1
    when match_vendor(resource) then 3
    else -1
    end
  end
 

Я думал, что это разорвет этот цикл, когда какой when -то элемент вернет true. Например match_amount(resource) amp;amp; match_vendor(resource) , вернет true — он case прерывается и возвращает 1. Как этого добиться?

Комментарии:

1. Во-первых, здесь нет цикла для прерывания. Во-вторых, вы правы — case прекратит дальнейшую оценку предложений when, как только найдет подходящее. Если это не относится к вашему коду, это означает, что проблема где-то в другом месте.

2. Ваш вопрос очень неясен. Вы пишете «Ruby останавливает итерацию в блоке case, если возвращает true», но в вашем коде нет итерации. Кроме того, вы пишете «Я думал, что это разорвет этот цикл», но в коде, который вы показали, цикла нет, так что такое «этот цикл», на который вы ссылаетесь? Также трудно сказать, что происходит, не зная определений resource , match_amount , match_vendor , и match_invoice_number . Пока их возвращаемые значения правильно реагируют на === сообщение, код должен работать так, как задумано.

Ответ №1:

В case resource ruby сравнивает ваш ресурс с каждым используемым выражением === . Кажется, что match... методы возвращают логические значения, так что вы всегда будете получать значение по умолчанию.

Чтобы сделать эту работу, вы могли бы избавиться от ресурса. С пустым регистром вы получите ожидаемое поведение.

 def score(resource)
  case
  when match_invoice_number(resource) then 0
  when match_amount(resource) amp;amp; match_vendor(resource) then 1
  when match_vendor(resource) then 3
  else -1
  end
end
 

Однако не рекомендуется использовать пустые регистры. If-else — это инструмент, который лучше решает эту задачу.

 def score(resource)
  if match_invoice_number(resource)
    3
  elsif match_amount(resource) amp;amp; match_vendor(resource)
    2
  elsif match_vendor(resource)
    1
  else
    0
  end
end