Ruby on Rails - Check My Code: Tips to Keep Ruby Code Smell-Free - ruby on rails tutorial - rails guides - rails tutorial - ruby rails



How to check my code in ruby?

  • In this, we will discuss a few common Ruby code smells and how to best freshen them.
  • Code smells are symptoms of a deeper problem, and by eliminating them, we can leave our code elegant and odor free!
  • Common code smells include long classes, large methods, dead code, and repetition.
  • These issues are not only bad practice, but they indicate that there is probably a structural issue with our code.
  • Code smells might not cause an error immediately, but they make code difficult to maintain and might cause errors for edge cases.
  • Below, we cover a few different smells, including dispensable code, long conditionals, classes with attributes but no methods, poor variable naming, and over commenting.
 learn ruby tutorial - codes in ruby check my code - ruby example
Learn ruby - ruby tutorial - learn ruby tutorial - codes in ruby check my code - ruby example - ruby examples - ruby programs

Check My Code for Smells: Ruby edition

Dispensable Code: If ___ Return True, Else Return False

  • The pattern, “If __ return true, else return false” shows up again and again.
  • Returning true or false from an if statement is redundant as we will see below.
  • This pattern is an example of code that is dispensable and will make our program bloated and difficult to read.
  • Below we discuss two different ways to code this pattern: one is long and redundant, and the other is concise and elegant.
  • Check out the following method on the Animal class, which determines if an animal is_a_peacock?.
class Animal
	attr_reader :type
	
	def initialize(type)
		@type = type
	end

	def is_a_peacock?
		if type == "peacock"
			return true
		else
			return false
		end
	end
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • Do you smell it? The conditional type == “peacock” already returns a boolean, so we don’t need to include it in an if statement. This six-line phrase can and should be simplified into just one line. See below:
class Animal
		attr_reader :type
	
	def initialize(type)
		@type = type
	end

	def is_a_peacock?(animal)
		type == "peacock"
	end
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • Ahh, that’s better! We will keep this in mind whenever we find ourselves falling into the “if ___ return true, else return false” pattern.
  • By removing dispensable code, we can make our code clean and easier to understand. Let’s move onto smellier smells!

Long Conditionals

  • There are a few different ways we can do this, but some are much more odorous than others
puts "What is your major?"
major = gets.chomp

case major
when "Biology"
	puts "Mmm the study of life itself!"
when "Computer Science"
	puts "I'm a computer!"
when "English"
	puts "No way! What's your favorite book?"
when "Math"
	puts "Sweet! I'm great with numbers!"
else
	puts "That's a cool major!"
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team

However, this strategy is still long and wordy. We can improve on this even further!

puts "What is your major?"
major = gets.chomp

# Set default response
major_responses = Hash.new("That's a cool major!")

# Add other responses
major_responses["Biology"] = "Mmm the study of life itself!"
major_responses["Computer Science"] = "I'm a computer!"
major_responses["English"] = "No way! What's your favorite book?"
major_responses["Math"] = "Sweet! I'm great with numbers!"

puts major_responses[major]
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • By mapping majors to responses, we can simply hash the major input and get the appropriate response as the output.
  • We set a default value that is returned if the major entered is not included in major_responses
  • After setting up our major/response mapper, we only need one line, which finds the response in constant time.
  • Note that if we were trying to write a solution that optimizes for space complexity, this would not be an appropriate solution.

Class With Attributes but No Methods

  • As we know, classes are used to organize objects that behave similarly and have the same properties.
  • But what if we have an item that has no methods or no actions? See below.
class Person

	attr_reader: :height, :hair_color, :dominant_hand, :iq, :astigmatic?

	def initialize(height, hair_color, dominant_hand, iq, astigmatic?)
		@height = height
		@hair_color = hair_color
		@dominant_hand = dominant_hand
		@iq = iq
		@astigmatic? = astigmatic?
	end

end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • As we can see, a Person has many attributes. But in our example, a Person does not have any actions.
  • For this reason, a class is not the best way to represent this object. While functionally, a Person class does the job, it is best practice to use a Ruby struct. Structs are used to create simple classes and can be initialized much more concisely.
  • Below are two different examples of how to create a struct.
Struct.new("Person", :height, :hair_color, :dominant_hand, :iq, :astigmatic?)
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team

Or,

Person = Struct.new(:height, :hair_color, :dominant_hand, :iq, :astigmatic?)
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • We can now create a person like so:
sally = Person.new(165, "red", :left, 180, true)
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • And Sally’s attributes can be accessed exactly like we access attributes for an instance of a class.
sally.height 			# => 165
sally.hair_color 		# => "red"
sally.dominant_hand		# => :left
sally.iq			# => 180
sally.astigmatic?		# => true
  • From now on, we can “de-smell” our code by using structs whenever we have an object that can be fully represented by only its attributes.
  • As a side note, structs also come in handy when dealing with node-based data structures such as linked lists, trees, and graphs.

Variable Naming

  • Name your variables appropriately. We’ve heard it before, and we’ll hear it again! While a, b, x, and, y are easy to type out, going back and understanding your logic days later is a pain.
  • Poor variable nomenclature is a symptom of unmaintainable code and should always be avoided. See below.
A = :fluorescent
B = :incandescent
C = :led

class Thing
	attr_reader :x
	
	def initialize(x)
		@x = x
	end

	def lightbulb
		if x == A || x == B || x == C
			puts "I am a lightbulb!!"
		else
			puts "I don't know what I am..."
		end
	end
end
class GarageItem
		attr_reader :type
	
		def initialize(type)
			@type = type
		end

	def am_i_a_lightbulb
		if type == :incandescent || type == :fluorescent || type == :led
			puts "I am a lightbulb!!"
		else
			puts "I don't know what I am."
		end
	end
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team

Now our code almost reads like plain English which makes it easy to understand and maintain.

Indexing Into JSON Objects with Long Chains

  • Let’s say we are trying to access data deep inside a large JSON object that we have imported and parsed into a Ruby hash.
  • This pattern is common when accessing APIs.
  • We want to access some piece of data that is inside a hash, which is in an array, which is in a hash, which is in another hash.
  • While it may be tempting to just keep indexing until we have arrived at our destination, this technique often leads to errors down the road.
  • Let’s take a look at this example response from a sample API that returns information about geographic regions.

Response for California

{  "California" => 
	{"Abbreviation" => "CA", 
	 "population" => 39144818, 
	"senators" => [ 
		{ "name" =>"Barbara Boxer", "party" => "Democratic", "website" => "https://www.boxer.senate.gov/" }, 

		{"name => "Diane Feinstein", "party" => "Democratic", "website" => "http://www.feinstein.senate.gov/public/"}
		]
	 }
}
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • If we want to use this API to find the email address of one of our senators , we may be tempted to write a method like so:
def get_first_senator_email(response, state)
	response[state]["senators"].first["email"]
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • While this method will work for most of the responses, we must consider the edge cases that it will fail on.
  • We can’t just assume every state will have senators and each of those senators will have emails.
  • Check out this response from the same API for Washington DC.

Response for Washington DC

{  "Washington DC" => 
	{"Abbreviation" => "DC", 
	 "population" => 658893, 
	senators => []
	 }
}
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • Washington DC has no senators (taxation without representation!), so our previous method get_senator_emails will throw an error like this one : NoMethodError: undefined method '[]' for nil:NilClass.
  • If we are not completely certain that our JSON object will have the same format for every possible response, it is dangerous to chain methods. Instead, we should write the get_senator_emails method like so:
def get_first_senator_email(response, state)
	senators = response[state]["senators"]	
	if senators.empty?
		raise ArgumentError, "No senator information available"
	else
		response[state]["senators"].first["email"]
	end
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • By checking the return value of senators before chaining another method onto it, we can provide the user with helpful error information.
  • We can now be confident when we call .first["email"] that we will not get a NoMethodError.
  • Every time we add another link to our chain, we have to be careful and check that the previous item will always be the expected return value.

Over and Under Commenting

  • The last code smell we cover in this tutorial is poor commenting.
  • Comments are important, but we should make sure that they supplement our code in a way that is helpful, not repetitive.
  • There is a fine line between comments that are useful and those that just obfuscate code.
  • Below is a sample of a method that determines if an integer, n, is prime. One solution is over commented, and the other has one much more useful comment.

Over Commented

def is_prime?(n)
	# loop until i * i is greater than n
	while i * i < n
		# check to see if n is evenly divisible by integer i
		if n % i == 0 
			# return false if it is
			return false
		end
		i += 1
	end
	# return true if n % i == 0 is never true
	true
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team

Helpfully Commented

def is_prime?(n)
	# Any factor greater than sqrt(n) has a corresponding factor less than 
	# sqrt(n), so once i >=sqrt(n) we have covered all cases
	while i * i < n
		if n % i == 0 
			return false
		end
		i += 1
	end
	true
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • As we can see, the first example’s comments just reiterate what the code is doing and doesn’t provide any extra information.
  • The second sample has a single helpful comment, and is not redundant.
  • One useful trick is to think of comments as an explanation of why we are doing something and the actual code as an explanation of how we are doing something

This ruby on rails tutorial page provides you the following key areas such as ruby , rail , ruby on rails , rail forum , ruby on rails tutorial , ruby tutorial , rails guides , rails tutorial , learn ruby , rails form_for , ruby rails , ruby class , what is ruby on rails , rails installer , ruby online , learn ruby on rails , ruby on rails jobs , rails find_by , install rails , easyrail , rubyonrails , link_to rails , ruby on rails developer , learn ruby the hard way , railscasts , ruby on rails examples , ruby on rails vs php , rails 4 , rails activerecord , rails generate , ruby and rails , ruby on rails download , install ruby on rails , ruby net http , what is rails , ruby app , ruby vs ruby on rails , ruby on rails windows , rails for zombies , ruby on rails book , ruby on rails development , ruby on rails ide , ruby on rails tutorial pdf

Related Searches to Check My Code: Tips to Keep Ruby Code Smell-Free