From: Rodrigo Rosenfeld Rosas Date: 2011-01-21T03:27:55+09:00 Subject: [ruby-core:34670] Re: Returning from the callee Em 20-01-2011 07:59, Jonas Pfenniger (zimbatm) escreveu: > 2011/1/20 Rodrigo Rosenfeld Rosas: >> Sometimes it is useful to be able to return from the callee method. For >> instance, consider a web application (how innovative, this is, right?): >> >> def verify_params(params) >> # some calculations over params >> render 'Invalid params' if params.invalid? >> return from callee >> end >> private :verify_params >> >> def some_url(params) >> verify_params(params) >> #useful code here >> end >> >> def another_url >> verify_params(params) >> #useful code here >> end > This is usually solved by using Kernel#throw and Kernel#catch > > def verify_params(params) > throw :early_exit, :invalid_params if params.invalid? > end > > def some_url(params) > verify_params(params) > > #...other stuff > end > > def dispatcher(request) > ret = catch(:early_exit) do > some_url(params) > end > if ret == :invalid_params > # handle issue > .. The problem with that approach is that it can only be used by the framework developers and not by the application developers. The last ones don't have direct access to the dispatcher method. Usually the frameworks already provide some filter feature that allows stopping the dispatcher in some conditions. This remembers me another feature I would like Ruby to have out-of-the-box but I'll talk about this in a separate thread. Usually a web framework will call some method from an application controller class. If the framework doesn't provide any means to filter some method, the user won't be able to do that with some auxiliar method in a simple way as described in my examples. A special case that illustrate how useful this feature could be is the "render" method, where the user expects the thread to be interrupted after the controller renders some output to the client. I wouldn't like to see some codes like this: return nil.tap { render text: 'failed' } unless request.valid? Best regards, Rodrigo.