2015-11-04 4 views
4

Я хотел бы иметь возможность вернуться из метода вызова, находясь внутри вызываемого метода.Ruby: return from call method

Пример:

def calling_method 
    # stuff 
    called_method 
    # more stuff 
end 

def called_method 
    # stuff 
    return_from_caller if foo # << I would like to return from calling_method 
    # more stuff 
end 

Есть простой способ для достижения этой цели?

«Грязный» способом я использую в данный момент заключается в следующем:

def calling_method 
    # stuff 
    called_method and return 
    # more stuff 
end 

def called_method 
    # stuff 
    return false if foo 
    # more stuff 
end 

Но это не вполне удовлетворительное, как я должен делать and return в вызывающем методе.

+0

Ruby, как и другие языки, при получении оператора return завершает метод. Вы можете установить переменную с содержимым и вернуться в конце этого метода. – gFontaniva

+0

Я честно не понимаю ваш комментарий. Не могли бы вы привести пример кода? – Mat

+0

Вы также можете создать исключение, если это имеет смысл семантически. – Felix

ответ

3

Думаю, вы не можете этого сделать.

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

На самом деле, do_something and return - довольно распространенный шаблон/прецедент, который вы увидите в коде Ruby/Rails.

Так, ИМО, это путь:

def calling_method 
    # stuff 
    called_method and return 
    # more stuff 
end 
+0

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

+0

К среднему времени вы можете посмотреть это сообщение: http://blog.arkency.com/2014/07/4-ways-to-early-return-from-a-rails-controller/ и http: //stackoverflow.com/questions/5539106/rails-render-and-exit-immediately and .... just google it :) –

+1

Первая ссылка подтверждает, что это действительно нормально, поэтому еще раз спасибо :) – Mat

1

Нечто подобное возможно только с блоками, которые имеют возможность вернуться непосредственно метод, дающий блок. Рассмотрим следующий пример:

# You don't need to specify &block here, it works the same if you omit it 
# I added it for clarity 
def calling_method(&block) 
    puts 'before' 
    puts yield 
    puts 'after' 
end 

Теперь вы можете вызвать calling_method с различными блоками и наблюдать за поведением метода:

Во-первых, мы называем его с обычным блоком, который возвращает простое значение

calling_method { 3 } 
# before 
# 3 
# after 
# => nil 

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

calling_method { next 23 } 
# before 
# 23 
# after 
# => nil 

Ключевое слово next эффективно является return для проков. Он завершает выполнение proc и возвращает любое значение (или nil по умолчанию).

Наконец, мы посмотрим на то, что происходит, когда мы используем break в блоке:

p calling_method { break 23 } 
# before 
# => 23 

При использовании break ключевого слова в Ruby, что происходит в том, что процедура возвращает и метод, который поддался block также немедленно возвращается со значением, заданным для ключевого слова break.

Таким образом, если вы можете переписать свою логику так, чтобы поведение, определенное в вашем called_method, можно было переписать в блоке и передать в ваш calling_method, тогда вы можете контролировать поведение возврата из блока.

Если вам нужно называть фактические методы, то техника called_method and return - это единственный способ.

0

Это должно сработать.Возврат из лямбда должен продолжать остаток потока

def calling_method 
    # stuff 
    lambda { called_method } 
    # more stuff 
end