2014-01-29 5 views
0

Так что этот метод иногда возвращает экземпляр класса Resource, а иногда возвращает «true».Метод иногда возвращает true, иногда возвращает экземпляр объекта

Кажется, я «исправил» проблему, добавив ключевое слово return, но я не уверен, почему это происходит в первую очередь. Я прошел через код с помощью отладчика RubyMine, и в обоих случаях он, похоже, придерживается одного и того же пути, но при этом возвращается другое значение.

Я только начал программировать на Ruby, так что это все для меня загадка ..

кажется, что проблема возникает только тогда, когда проверка проходит.

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

Вот проблемный метод:

def self.create_or_update(attributes = nil, options = {}, &block) 
    if attributes.is_a?(Array) 
     attributes.collect { |attr| create_or_update(attr, options, &block) } 
    else 
     begin 
     object = Resource.find_by_article_id(attributes[:article_id]) 
     object.update_attributes!(attributes, options) 
     rescue 
     object = new(attributes, options, &block) 
     ensure 
     object.save 
     return object # for some reason, if you just leave out the "return" keyword, sometimes it returns "true" instead of an instance of the Resource class.. ?????? 
     end 
    end 
    end 

EDIT:

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

Последнее утверждение внутри «обеспечить» не рассматривалось как возвращаемое значение, хотя это был последний оператор, который должен обрабатываться в методе. Что на самом деле получили лечение в качестве возвращаемого значения было возвращаемое значение из object.update_attributes! (Атрибуты, опционы)

Так в основном ..

def method 
    true 
ensure 
    false 
end 

Этот метод возвращает истинный, который, кажется, контр- интуитивно понятный, поскольку «false» выполняется последним.

Кажется, что это несоответствие в спецификации языка/возвращаемом методе, не так ли?

ответ

0

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

Последнее утверждение внутри «обеспечить» не рассматривалось как возвращаемое значение, даже если это последний оператор, который обрабатывался в методе. возвращаемым значением было возвращаемое значение от object.update_attributes! (Атрибуты, опционы)

Так в основном ..

def method 
    true 
ensure 
    false 
end 

Этот метод возвращает истинный, который, кажется нелогичным, как 'ложный' запускается на выполнение последней.

1

Прежде всего, совет: я бы не использовал rescue, не указав исключение, которое вы хотите поймать. Это может вызвать всевозможные проблемы.

Причина, по которой этот метод возвращает разные значения, заключается в том, что в методе ruby ​​возвращается значение последнего выполняемого оператора.

http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls#Return_Values

В коде у вас есть состояние, а также спасение и обеспечения. В зависимости от того, в какой части кода вы входите, будет возвращено другое значение. Например, attributes.collect будет возвращать что-то другое, чем new

Если поместить объект на последней строке метода:

def self.create_or_update(attributes = nil, options = {}, &block) 
    if attributes.is_a?(Array) 
     .. 
    else 
     begin 
     .. 
     end 
    end 
    object 
    end 

Затем объект всегда будет возвращен.

1

Как сказал Киран Эндрюс, одна вещь - это если и вернуть другую вещь, хотя сбор должен возвращать массив.

Другое дело, если запись не существует, объект равен nil, затем nil.update_attributes! будет поднимать исключение, легко судить, является ли объект нулем вместо исключения catch. Если update_attributes! исключение, вы просто «новое» и не делаете ничего другого? Если проверка не удалась, может ли «новая» гарантировать, что «новое» действительно, и что вы хотите?

Если запись не существует, то «новое» легко понять, но я не уверен, что update_attributes! потерпел неудачу также нуждаются в «новый.

Наконец, если

object.update_attributes!(attributes, options) 

успеха, не должны„object.save“.

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