Skip to content

Instantly share code, notes, and snippets.

@jameshwang
Last active December 18, 2015 10:49
Show Gist options
  • Save jameshwang/5771563 to your computer and use it in GitHub Desktop.
Save jameshwang/5771563 to your computer and use it in GitHub Desktop.

Refactoring Ruby Edition

Chapter 6: Composing Methods

Extract Method

Basically just take a block of code and move it out to its own method.

Make sure the variables are passed in as arguments.

Inline Method

Sometimes, we want to make methods to help clarify the code to the reader. However, sometimes, it may be best to just eliminate the method if it's a one liner and makes more sense by itself.

def get_rating
  more_than_five_late_deliveries ? 2 : 1
end

def more_than_five_late_deliveries
	@number_of_late_deliveries > 5
end
Becomes
def get_rating
  @number_of_late_deliveries > 5 ? 2 : 1
end

Inline Temp

If the temp can be eliminated, remove it and just call what the temp is assigned.

Note that in situations of bad performance or datetime changes, having temp variables are better.

Replace Temp with Query

In situations where a temp variable is assigned a calculation, create a query method and call that instead of using the temp variable

In the motivation to remove temps, the key to why we want to remove them is because in a chunk of code, the state of that temp could change. So to take a functional spin, try to use methods and if you must use temps variables, try to make them not change after they're defined.

Replace Temp with Chain

Sometimes, when we create many temp variables, we then send a message to each variable. Instead, try to chain them to eliminate variables. Note, when creating custom methods, make sure that every "flow" returns something valid and not a "Nil"

Introduce Explaining Variable

In situations where a good variable name will help clarify the code vs the complex method name, use a variable. Note again that it shouldn't change state!

Split Temporary Variable

Sometimes, we want to have a temp variable be assigned multiple times throughout the scope of that variable. Don't!! Just use another variable name. Variables are cheap in ruby.

Replace Method with Method Object

If you have many local variables needed for a replaced method, use a replace method object and make the local variables instances variables.

Substitute Algorithm

Replace Loop with Collection Closure Method

Use ruby's emumerables!

Extract Surrounding Method

Use blocks and yields to create more DRYness in your code

Introduce Class Annotation

Use of a method to give it's arguments certain functions. Similary to "has_many", "attr_reader", etc.

Introduce Named Parameters

When a method starts getting many arguments, it's hard to read what those arguments are for. So use a hash paramater to define them on both sides. The method doing the work and the area of the code that is calling it.

Remove Named Paramater

If the arguments are self explanatory, then remove the hash. ActiveModel#find as an example.

Chapter 7: Moving Features Between Objects

Move Method

If the methods starts showing signs of "feature envy" like account.new, account.send, and account.find, maybe it should be moved to account?

Move Field

Again, like the method, move the field if it doesn't belong and the code shows it.

Extract Class

If the current class is doing more than 1 responsibility, it should be extracted out.

Chapter 9: Conditional Refactoring

Decompose Conditional

if amount > 10 && amount < 100
	# do something
end

if valid_amount?
	# do something
end

def valid_amount?
	amount > 10 && amount < 100
end

Beware the triangle (in javascript, callback hell)

nested if/else/end statements will confuse readers. Consolidate or use guard statements

Replace Conditional with Polymorphism

Introduce Null Object

Note: Has anyone used the assert method to make sure the conditions are met before the rest of the code runs?

Chapter 10: Making Method Calls Simpler

Separate Query from Modifier

This goes back to what Sandi talked about with regards to tests. methods should be queries or commands

Factory method

Creates the correct instance of a class based on a set of conditions

Gateway (same as Adapter Pattern?)

Chapter 11: Dealing with Generalizations

Extract Module (sharing behavior)

Chapter 12: Big Refactorings

Convert Procedural Design to Objects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment