From a web application point of view, you''re usually done after you deliver some content to the client, which in Rails means a render or redirect call usually. For 99.99% of the cases, there''ll be a return following a render or redirect inside some "if". Some might prefer something like (render login_url; return) unless authenticated? Others will prefer something more verbose like unless authenticated? render login_url return end Others will rely on some undocumented feature of render that might change any time: render login_url and return unless authenticated? render (or redirect_to) is not guaranteed to return a truthy value, specially because it really doesn''t make any sense for the returning result to have any meaning. So, I''m suggesting that Rails could support some automatic "return" after each call to render or redirect_to, by calling the method inside a catch-throw block. For example: class Dispatcher def dispatch(controller, action) catch :redirected_or_rendered do controller.send action end end end class AbstractController def render(*args) # or redirect_to do_render(*args) throw :redirected_or_rendered end end Maybe new method names like render_and_return and redirect_and_return could be added for backward compatibility, although I would really prefer to use render and redirect_to with this behavior built-in. Maybe we could add some option like "Rails.application.config.automatic_return_from_render_or_redirect = true". Is there any interest on adding such behavior to Rails? Cheers, Rodrigo. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
throw/catch for flow control is bad. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Nope, I think the current way of doing things is just fine. On 20/12/2011, at 9:51, Rodrigo Rosenfeld Rosas <rr.rosas@gmail.com> wrote:> From a web application point of view, you''re usually done after you deliver some content to the client, which in Rails means a render or redirect call usually. > > For 99.99% of the cases, there''ll be a return following a render or redirect inside some "if". > > Some might prefer something like > > (render login_url; return) unless authenticated? > > Others will prefer something more verbose like > > unless authenticated? > render login_url > return > end > > Others will rely on some undocumented feature of render that might change any time: > > render login_url and return unless authenticated? > > render (or redirect_to) is not guaranteed to return a truthy value, specially because it really doesn''t make any sense for the returning result to have any meaning. > > So, I''m suggesting that Rails could support some automatic "return" after each call to render or redirect_to, by calling the method inside a catch-throw block. > > For example: > > class Dispatcher > def dispatch(controller, action) > catch :redirected_or_rendered do > controller.send action > end > end > end > > class AbstractController > def render(*args) # or redirect_to > do_render(*args) > throw :redirected_or_rendered > end > end > > Maybe new method names like render_and_return and redirect_and_return could be added for backward compatibility, although I would really prefer to use render and redirect_to with this behavior built-in. > > Maybe we could add some option like "Rails.application.config.automatic_return_from_render_or_redirect = true". > > Is there any interest on adding such behavior to Rails? > > Cheers, > > Rodrigo. > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
On Mon, Dec 19, 2011 at 11:56 PM, Steve Klabnik <steve@steveklabnik.com> wrote:> throw/catch for flow control is bad.Indeed it is. It''s the one thing in Sinatra I always disliked. If I had to choose, I would go down the path of render/redirect returning a response, so you would do something like `return render :new` or `return redirect_to @object`. This has the added bonus that it''s compatible with 99.9% of the uses of render and redirect (being the last line of an action/conditional) thanks to the implicit returns. def create @obj = Obj.new(…) if @obj.save redirect_to @obj, notice: … else render :new end end That still works as expected. But if you did: def create render :foo render :bar end You get the response generated by "render :bar" and the other one is ignored. Because it''s just an object returned, instead of some black magic depending on class state. That said, this would require quite the refactoring in ActionPack. But it would be much cleaner, IMHO. Cheers, -foca> -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Yehuda Katz (ph) 718.877.1325 2011/12/19 Nicolás Sanguinetti <hi@nicolassanguinetti.info>> On Mon, Dec 19, 2011 at 11:56 PM, Steve Klabnik <steve@steveklabnik.com> > wrote: > > throw/catch for flow control is bad. > > Indeed it is. It''s the one thing in Sinatra I always disliked. > > If I had to choose, I would go down the path of render/redirect > returning a response, so you would do something like `return render > :new` or `return redirect_to @object`. > > This has the added bonus that it''s compatible with 99.9% of the uses > of render and redirect (being the last line of an action/conditional) > thanks to the implicit returns. > > def create > @obj = Obj.new(…) > > if @obj.save > redirect_to @obj, notice: … > else > render :new > end > end > > That still works as expected. > > But if you did: > > def create > render :foo > render :bar > end > > You get the response generated by "render :bar" and the other one is > ignored. Because it''s just an object returned, instead of some black > magic depending on class state. > > That said, this would require quite the refactoring in ActionPack. >It actually wouldn''t require major refactoring. The work we did in 3.0 made this possible. Unfortunately, it breaks some common scenarios: def create render :foo Rails.logger.info "hi" end def create @bar = "1" # lack of render here currently means implicit render, but now the return value is a String # so it would be rendered end etc.> But it would be much cleaner, IMHO. > > Cheers, > -foca > > > -- > > You received this message because you are subscribed to the Google > Groups "Ruby on Rails: Core" group. > > To post to this group, send email to rubyonrails-core@googlegroups.com. > > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. > > > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Rodrigo Rosenfeld Rosas
2011-Dec-20 12:38 UTC
Re: automatic return from render and redirect
Em 19-12-2011 23:56, Steve Klabnik escreveu:> throw/catch for flow control is bad.raise-rescue is intended for exception handling, while catch-throw is intended for regular control flow in Ruby. Another possible syntax would be redirect_to and render returning an object that would respond to ''and_return'', like: redirect_to(login_path).and_return unless authenticated? This reads much better than "return render ..." and is also backward compatible... -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
> raise-rescue is intended for exception handling, while catch-throw is > intended for regular control flow in Ruby.Right. There''s a reason you don''t see it often in Ruby code bases. It''s slow, hard to understand, and just generally a bad idea. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Rodrigo Rosenfeld Rosas
2011-Dec-20 13:25 UTC
Re: automatic return from render and redirect
Em 20-12-2011 10:59, Steve Klabnik escreveu:>> raise-rescue is intended for exception handling, while catch-throw is >> intended for regular control flow in Ruby. > Right. There''s a reason you don''t see it often in Ruby code bases. > It''s slow, hard to understand, and just generally a bad idea.Let me know if you find any performance impact on this application: https://github.com/rosenfeld/ctbenchmark -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.