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
if !tweets.empty? puts “timeline” puts tweets end
is better the next code
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
if tweets.empty? puts “you dont have tweets” else pust tweets end
At the moment to use the nil
if result_proces != nil puts “good result” end
The correct way is only
if result_process puts “good job” end
More conditionals for example if you want to evaluated some string the correct way can be
if string.length Do something end
inline conditionals
if password.lenght < 8 pust “The password is short” end
In one line the conditional looks like:
puts “The password is short” if password.lenght < 8 puts “fail” unless username
More conditionals we can see the next
if user if user.signed_in? #Some logic here end end
We can write better the next
if user && user.signed_in? ## end
Short circuit assigment
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
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:
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
i_was_no_set || = 3 puts i_was_not_set #print 3
New example for assigments
we have the next code
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:
options[:country] || = ‘us’ options[:privacy] || = true options[:geotag] || = true
Conditionals return values, we can the next code:
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:
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
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
games = ["Super Mario Bros.", "Contra", "Metroid", "Mega Man 2"] if !games.empty? puts "Games in your vast collection: #{games.count}" end
Result code
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
games = ["Super Mario Bros.", "Contra", "Metroid", "Mega Man 2"] unless games.empty? puts "Games in your vast collection: #{games.count}" end
Result Code
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
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
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
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
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
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
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
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
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
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
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
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
def search_index(games, search_term) search_index = games.find_index(search_term) || "Not Found" end
No Comments