16 Sep Learning ruby part 1 conditionals, good and bad code
In the next code we’ll see:
- Using conditionals in ruby: If, Else, unless and when we should use one or other one
- How to evaluate a nill condition
- Sort circuit assignment (conditional in one line)
The good code and the bad code
1 2 3 4 | if !tweets.empty? puts “timeline” puts tweets end |
is better the next code
1 2 3 4 | unless tweets.empty? puts “timeline” puts Tweets end |
but when we need to use and else condition is bad to use the unless and is better use the if
1 2 3 4 5 | if tweets.empty? puts “you dont have tweets” else pust tweets end |
At the moment to use the nil
1 2 3 | if result_proces != nil puts “good result” end |
The correct way is only
1 2 3 | if result_process puts “good job” end |
More conditionals for example if you want to evaluated some string the correct way can be
1 2 3 | if string.length Do something end |
inline conditionals
1 2 3 | if password.lenght < 8 pust “The password is short” end |
In one line the conditional looks like:
1 2 | puts “The password is short” if password.lenght < 8 puts “fail” unless username |
More conditionals we can see the next
1 2 3 4 5 | if user if user.signed_in? #Some logic here end end |
We can write better the next
1 2 3 | if user && user.signed_in? ## end |
Short circuit assigment
1 2 3 | result = nil || 1 #this will return 1 result = 1 || nil #this will return 1 result = 1 || 2 #this will return 1 |
More examples sort circuit
1 2 3 | def sign_in current_session || sign_user_in end |
Conditional assigments
the next is a conditional assigment to asign one value to a variable, we can observe in the second line that if the var is nil o empty we assign and value 2:
1 2 3 | i_was_set = 1 i_was_set || = 2 puts i_was_set #print 1 |
For example in the next example if we are not assigne some value before at do the conditional then this will ocurr
1 2 | i_was_no_set || = 3 puts i_was_not_set #print 3 |
New example for assigments
we have the next code
1 2 3 | options[ :country ] = ‘us’ if options[ :country ]. nil ? options[ :privacy ] = true if options[ :privacy ]. nil ? options[ :geotag ] = true if options[ :geotag ]. nil ? |
We can refactor with the next code:
1 2 3 | options[ :country ] || = ‘us’ options[ :privacy ] || = true options[ :geotag ] || = true |
Conditionals return values, we can the next code:
1 2 3 4 5 | if list_name options[ :path ] = ‘/ #{user_name} / #{last_name}’ else options[ :path ] = ‘ #{user_name}’ end |
We can refactor the before code with the next one:
1 2 3 4 5 | options[ :path ]= if list_name ‘/ #{user_name} /#{last_name}’ else ‘ #{user_name}’ end |
Because by default ruby return a value for example in one function
1 2 3 4 5 6 7 | def list_name if list_name ‘/ #{user_name} / #{last_name}’ else ‘ #{user_name}’ end end |
And now lets go to do some exercise to practice a little:
Unless
We’re putting together a system to manage our vast video game collection that we just can’t seem to part with. Using ifwith negative conditions can be tough to read. Refactor the code below to use unless rather than if.
Origin code
1 2 3 4 | games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] if !games.empty? puts "Games in your vast collection: #{games.count}" end |
Result code
1 2 3 4 | games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] unless games.empty? puts "Games in your vast collection: #{games.count}" end |
Inline Statements
Doing a full unless statement is sometimes too much. Refactor the method below to use a single-line unless statement.
Origin code
1 2 3 4 | games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] unless games.empty? puts "Games in your vast collection: #{games.count}" end |
Result Code
1 2 | games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] puts "Games in your vast collection: #{games.count}" unless games.empty? |
Let’s implement a simple search feature – for our naive implementation, we search for a game by its exact title, and if it’s found, we show it. Comparing something with nil in an if statement isn’t needed in Ruby. Refactor the code below to run without the nil comparison.
Origin code
1 2 3 4 5 6 7 8 | search = "Contra" games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] search_index = games.find_index(search) if search_index != nil puts "Game #{search} Found: #{games[search_index]} at index #{search_index}." else puts "Game #{search} not found." end |
Result code
1 2 3 4 5 6 7 8 | search = "Contra" games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] search_index = games.find_index(search) if search_index puts "Game #{search} Found: #{games[search_index]} at index #{search_index}." else puts "Game #{search} not found." end |
Let’s clean up our code to make it search within each game title and show all the results. If it’s an exact match, we’ll show something special. Clean up the code below to short circuit the if statement.
Origin code
1 2 3 4 5 6 7 8 9 10 | search = "Super Mario Bros." games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] matched_games = games.grep( Regexp . new (search)) # Found an exact match if matched_games.length > 0 if matched_games.include?(search) puts "Game #{search} found." end end |
Result Code
1 2 3 4 5 6 7 8 | search = "Super Mario Bros." games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] matched_games = games.grep( Regexp . new (search)) # Found an exact match if matched_games.length > 0 && matched_games.include?(search) puts "Game #{search} found." end |
If no search is entered, we’ll display all games. Notice the first line below where we’re setting search to an empty string? Change this to use conditional assignment.
Origin code
1 2 3 4 5 6 7 | search = "" unless search games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] matched_games = games.grep( Regexp . new (search)) puts "Found the following games..." matched_games. each do |game| puts "- #{game}" end |
Result code
1 2 3 4 5 6 7 | search ||= "" games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] matched_games = games.grep( Regexp . new (search)) puts "Found the following games..." matched_games. each do |game| puts "- #{game}" end |
Clean up the code below to only set search_result once by using a conditional return on the if statement.
Origin code
1 2 3 4 5 6 7 8 9 | search = "Contra" games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] search_index = games.find_index(search) if search_index search_result = "Game #{search} found: #{games[search_index]} at index #{search_index}." else search_result = "Game #{search} not found." end puts search_result |
Result Code
1 2 3 4 5 6 7 8 9 | search = "Contra" games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] search_index = games.find_index(search) search_result= if search_index "Game #{search} found: #{games[search_index]} at index #{search_index}." else "Game #{search} not found." end puts search_result |
One of the most common places to use conditional returns is within methods. Refactor the code below, removing the search_result variable all together.
Origin code
1 2 3 4 5 6 7 8 9 10 11 12 | def search(games, search_term) search_index = games.find_index(search_term) search_result = if search_index "Game #{search_term} found: #{games[search_index]} at index #{search_index}." else "Game #{search_term} not found." end return search_result end games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] puts search(games, "Contra" ) |
Result code
1 2 3 4 5 6 7 8 9 10 11 | def search(games, search_term) search_index = games.find_index(search_term) if search_index "Game #{search_term} found: #{games[search_index]} at index #{search_index}." else "Game #{search_term} not found." end end games = [ "Super Mario Bros." , "Contra" , "Metroid" , "Mega Man 2" ] puts search(games, "Contra" ) |
Using Short-Circuit Evaluation can clean up your code a great deal. Update the following method to use short circuit evaluation. While you’re at it, why not try reducing the entire method to one line?
origin code
1 2 3 4 5 6 7 8 | def search_index(games, search_term) search_index = games.find_index(search_term) if search_index search_index else "Not Found" end end |
Result code
1 2 3 | def search_index(games, search_term) search_index = games.find_index(search_term) || "Not Found" end |
No Comments