2012-06-12 4 views
1

Я работаю в Ruby и нашел необходимость иметь условные операторы возврата в конце некоторых/большинства моих методов.Ruby: лучший способ обработки нескольких возвратов

Вот что у меня есть:

# <ident-list> -> [ident] <ident-A> 
    def ident_list(keys) 
    id = nil 
    ident_a_node = nil 

    ## method hidden 

    return IdentifierListNode.new(id, ident_a_node) unless id.nil? 
    return nil 
    end 

Есть ли лучше/уборщик способ идти об этом с несколькими возвращается?

ответ

5

Последняя строка перед end может быть просто

IdentifierListNode.new(id, ident_a_node) unless id.nil? 

Последнее утверждение выполнено это возвращаемое значение метода. Если id равен нулю, инструкция будет оцениваться как nil, а если нет, то будет возвращен новый экземпляр IdentifierListNode.

+0

Спасибо, я не знал, что он вернет нуль, если не будет явно там –

1
return (id.nil? ? nil : IdentifierListNode.new(id, ident_a_node)) 
+2

Это менее читаемым, чем его версия, имхо. –

0

Стоя перед вами, вы будете делать нолевые чеки повсюду.

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

How to avoid “!= null” statements in Java?

+0

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

3

При использовании двойного амперсанда (И оператора), правая рука вернется, так что вы можете сократить ответ Адриана на это:

return (id && IdentifierListNode.new(id, ident_a_node)) 

В первой части условия проверяет наличие id, nil будет возвращен. Если это последнее утверждение, вы можете удалить «вернуться» в целом, так как это подразумевается в Ruby, оставив только:

id && IdentifierListNode.new(id, ident_a_node) 

протестирована со следующими:

def check(input) 
    input && input * 2 
end 

check(nil) # => nil 
check(123) # => 246 
1

В то время как вы можете сделать возврат в однострочный, это один из тех случаев, когда я думаю, что быть немного более явным, а скимм стоит того. Это, конечно, спорно, но после работы на много разных команды с Рубистами Я думаю, что если вы идете к версии в одной строки есть хороший шанс, что вы (или другой член вашей команды) можете извратить потенциальные состояния выхода при просмотре код позже.

Я хотел бы предложить:

def ident_list(keys) 
    id = nil 
    ident_a_node = nil 

    ## method hidden 

    return IdentifierListNode.new(id, ident_a_node) unless id.nil? 
    nil 
end 

или если вы не заботитесь о разнице между ложной/ноль в этом случае, даже лучше:

def ident_list(keys) 
    id = nil 
    ident_a_node = nil 

    ## method hidden 

    return IdentifierListNode.new(id, ident_a_node) if id 
    nil 
end 

Довольно много всех, кто работал в рубине на некоторое время понимает, что окончательное значение в методе неявно возвращается (т. е. оно вернет нуль, если возврат не заблаговременно), - и вы можете получить этот взгляд. Мой опыт заключается в том, что многие люди, которые долгое время работали с рубином, все еще сталкиваются с изменениями & & и менее явными условными доходами.

Если вы решили использовать один вкладыш, я бы с ответом Райана, в основном потому, что это идиома, которая используется довольно часто и менее вероятно, следует путать:

def ident_list(keys) 
    id = nil 
    ident_a_node = nil 

    ## method hidden 

    id && IdentifierListNode.new(id, ident_a_node) 
end 

Одно предостережение к этот подход является то, что вы на самом деле в конечном итоге с тремя возможными состояниями возвратных вместо двух (другие варианты будут возвращать только ноль или ваш новый IdentifierListNode):

  • Когда идентификатор равен нулю, возвращаемое значение будет нулевой
  • WhenИдентификатор ложно, возвращаемое значение будет ложным
  • Когда идентификатор ничего другого, возвращаемое значение будет ваш IdentifierListNode объект
Смежные вопросы