2016-02-08 3 views
0

Я пробовал читать некоторые уроки по рефакторингу, и я борюсь с условностями. Я не хочу использовать тернарный оператор, но, возможно, это нужно извлечь в методе? Или есть умный способ использовать карту?ruby ​​- refactoring if else statement

detail.stated = if value[:stated].blank? 
        nil 
       elsif value[:stated] == "Incomplete" 
        nil 
       elsif value[:is_ratio] == "true" 
        value[:stated] == "true" 
       else 
        apply_currency_increment_for_save(value[:stated]) 
       end 
+0

Это код Rails? - 'blank?' определяется Rails, а не частью Ruby –

+0

Что вы хотите сделать, если это nil? например, поднять ошибку/умереть/выйти? – zee

+0

да это рельсы – user3437721

ответ

3

Если переместить эту логику в метод, это может быть сделано намного ровнее благодаря ранней return (и именованных аргументов):

def stated?(stated:, is_ratio: nil, **) 
    return if stated.blank? || stated == "Incomplete" 
    return stated == "true" if is_ratio == "true" 
    apply_currency_increment_for_save(stated) 
end 

Тогда ...

detail.stated = stated?(value) 
1
stated = value[:stated] 
detail.stated = case 
    when stated.blank? || stated == "Incomplete" 
    nil 
    when value[:is_ratio] == "true" 
    value[:stated] == "true" 
    else 
    apply_currency_increment_for_save stated 
end 

Что происходит:   когда case используется без выражения, оно становится цивилизованным эквивалентом if ... elsif ... else ... fi.

Вы можете использовать свой результат тоже, так же, как с if...end.

0

Переместить код в apply_currency_increment_for_save и сделать:

def apply_currency_increment_for_save(value) 
    return if value.nil? || value == "Incomplete" 
    return "true" if value == "true" 
    # rest of the code. Or move into another function if its too complex 
end       

Логика инкапсулируется и она занимает 2 строки только

+0

Логика 'apply_currency_increment_for_save' теперь будет перепутана, поскольку она делает больше, чем« применяет приращение валюты », как в случае, когда она возвращает« истина »- в некотором смысле она будет нарушайте принцип единой ответственности (SRP) –

+0

Я не согласен, так как ответственность «определяется» от 'value'. Поэтому вы можете просто переименовать его в 'parse_stated' или что-то в этом роде. Или, как я прокомментировал, вы можете переместить остальную часть кода в другую функцию. В текущем коде также не очень понятно, почему функция, называемая 'apply_currency_increment_for_save', возвращает состояние. Основная идея состоит в том, чтобы удалить этот случай и нажать его на функцию, где она более читаема. – dgmora

0

Мне нравится @ Иордания. Тем не менее, кажется, что вызов неполный - параметр is_ratio также выбран из значения, но не указан.

Только ради аргумента я предлагаю вам сделать еще один шаг и предоставить класс , который очень узко ориентирован на оценку «заявленного» значения. Это может показаться экстремальным, но оно соответствует понятию единой ответственности (ответственность оценивает «ценность» для заявленного - в то время как объект «детали» может быть сфокусирован на чем-то другом и просто использует оценку).

Было бы выглядеть примерно так:

class StatedEvaluator 
    attr_reader :value, :is_ratio 

    def initialize(value = {}) 
    @value = ActiveSupport::StringInquirer.new(value.fetch(:stated, '')) 
    @is_ratio = ActiveSupport::StringInquirer.new(value.fetch(:is_ratio, '')) 
    end 

    def stated 
    return nil if value.blank? || value.Incomplete? 
    return value.true? if is_ratio.true? 
    apply_currency_increment_for_save(value) 
    end 
end 

detail.stated = StatedEvaluator.new(value).stated 

Обратите внимание, что это делает использование Rails' StringInquirer class.

+0

«Тем не менее, кажется, что вызов неполный ...» Похоже, возможно, вы не знакомы с [ключевыми аргументами] (https://www.google.com/search?q=ruby+keyword+arguments) в Ruby. Подпись метода 'def указано?(указано :, is_ratio: nil) 'указывает, что метод принимает Hash в качестве аргумента, а значения Hash с ключами': said' и ': is_ratio' будут извлечены из него в локальные переменные' assert' и 'is_ratio ', соответственно (последнее со значением по умолчанию« nil »в его отсутствии). –

+0

Спасибо, Иордания. Я, по сути, знаком с аргументами ключевого слова. Мой комментарий немного выключен. Проблема, которая может возникнуть из вашего примера, связана с возможностью того, что хэш имеет больше ключей, чем просто «указано» и «is_ratio». Извините за смешение. – AndyV

+0

О, я вижу. Хороший улов. Я обновил свой ответ. –