Project

General

Profile

Feature #12608

Updated by LucianCancescu (Lucian Cancescu) almost 8 years ago

Hi, 

 I would like to propose the replacement of the `unless` statement in Ruby.  

 # Problem description: 
 Unless is complex and my arguments are: 

 * I often see in projects `unless ... else`: 

 ~~~ ruby 
 unless user 
   redirect_to_login 
 else  
   render_profile 
 end 
 ~~~ 


 * Using `unless` with conditionals makes it very hard to understand: 

 ~~~ ruby 
 unless user || tenant do 
   user_and_tenant_are_present 
 end 
 ~~~ 
 Put an else to the conditional above and you can easily spend a few minutes to correctly understand what the code does. 

 Ruby is focuses on simplicity. I find both the examples above speaking against it. I have seen many Ruby projects, written by different people, and in most of them you see `unless` being abused in some way. 

 There is another aspect, when you see unless you have to keep a `not` in mind. The problem with that is that you have to negate all you read afterwards. You have to remove the negation when an else appears and you have to carefully read the negation with parenthesis in mind when `unless` contains boolean conditions. It's a huge complexity which can be avoided by simply using something else. 

 # Proposed solution: 
 How can we reduce the complexity? Other languages, for instance Swift, have introduced the `guard` [1] statement. 

 `guard` can replace `unless` in Ruby and the complex scenarios from above would become impossible: 

 Example 1 from above translates to: 

 ~~~ ruby 
 guard user else 
   return user_is_missing 
 end 
 # do something with the user 
 render_profile 
 ~~~ 

 Example 2 from above translates to: 

 ~~~ ruby 
 guard user && and tenant else 
   return user_or_tenant_missing 
 end 
 # do something with the user and the tenant 
 ~~~ 

 Not only the conditions become easier to read, but it reduces a lot the complexity of the code. 

 My suggestion is to add `guard` to the language and make it replace `unless`. What do you think? 

 Thanks, 
 Lucian 

 [1] Guard in Swift: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/guard-statement

Back