Как упростить этот метод в рубиновой манере? - PullRequest
1 голос
/ 21 ноября 2010

Я недавно работал над упрощением метода Ruby, который я не писал.Это часть унаследованного проекта, написанного коллегой.В целом, мы проделали довольно хорошую работу, не накапливая долг кода, но есть несколько методов, которые требуют любви.

Метод, который я упрощал, изначально представлял собой массу вложенных блоков if-else.Я определил, что делает метод, и упростил метод, чтобы больше не было вложенных ifs.

Теперь я хочу еще больше упростить это, и, если возможно, я хочу исключить все, кроме одного return утверждения.Этот метод длиннее этого, но это общая концепция того, как он выглядит сейчас:

def return_bool
  return false unless condition1 && condition2
  @var = SomeClass.getter(foo)
  return true unless var.someProperty != 0
  @stuff = @var.getsomething id
  return false unless @stuff && somethingElse
  data = JSON.parse(@stuff)
  @stuff.each do |stuff|
    return false if data[stuff['something']] != stuff['anotherSomething']
  end
  return true
end

Я думал об использовании raise и обработке исключений для сокращения операторов return, но еслинапример, condition1 ложно, это не исключительная ситуация, я ожидаю этого в определенные моменты времени.

Как я могу уменьшить количество return операторов, предпочтительно до одного?Если возможно, я бы предпочел неявно вернуться, если смогу.

Ответы [ 3 ]

2 голосов
/ 21 ноября 2010

Используйте ExtractMethod, чтобы разделить метод на более мелкие логические части.Ваши тесты должны помочь вам убедиться, что вы ничего не сломали.http://www.refactoring.com/catalog/extractMethod.html

  def return_bool
    some_condition? &&
       var_is_valid? &&
       stuff_is_valid? &&
       parsed_stuff_has_something?
  end

  def get_var
    @var = SomeClass.getter(foo)
  end

  def get_stuff
    @stuff = @var.getsomething id
  end

  def some_condition?
    condition1 && condition2
  end

  def var_is_valid?
    get_var.someProperty == 0
  end

  def stuff_is_valid?
    get_stuff && somethingElse
  end

  def parsed_stuff_has_something?
    data = JSON.parse(@stuff)
    @stuff.each do |stuff|
      return false if data[stuff['something']] != stuff['anotherSomething']
    end
    true
  end
1 голос
/ 21 ноября 2010

Используйте .all? вместо последнего .each цикла:

def return_bool
  return false unless condition1 && condition2
  @var = SomeClass.getter foo
  return true unless var.someProperty != 0
  @stuff = @var.getsomething id
  return false unless somethingElse && @stuff
  data = JSON.parse @stuff
  @stuff.all? do |stuff|
    data[stuff['something']] == stuff['anotherSomething']
  end
end

Кстати, возвращает против, если похоже на священную войну.Я предпочитаю возврат.
Кроме того, если вам не нравится возврат, как насчет этого?

def return_bool
  condition1 && condition2 && (
    @var = SomeClass.getter foo
    var.someProperty.zero? || (
      (@stuff = @var.getsomething id) && somethingElse && (
        data = JSON.parse @stuff
        @stuff.all? do |stuff|
          data[stuff['something']] == stuff['anotherSomething']
        end ) ) )
end
0 голосов
/ 21 ноября 2010

Пример кода не из чего-то, что работает, потому что Ruby отказался бы выполнить определение этого метода.

Вот как я мог бы его распутать, но без примеров значений для любой из локальных переменных или определенияиз SomeClass нет способа проверить это.

def return_bool
  if (condition1 && condition2)
    @var = SomeClass.getter(foo)
    if (var.someProperty == 0)
      @stuff = @var.getsomething id
      if (! (@stuff && somethingElse))
        data = JSON.parse(@stuff)
        @stuff.each do |stuff|
          return false if data[stuff['something']] != stuff['anotherSomething']
        end
      end
    end
  end
  return true
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...