Skip to content

Instantly share code, notes, and snippets.

@richievos
Created May 23, 2012 05:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save richievos/2773412 to your computer and use it in GitHub Desktop.
Save richievos/2773412 to your computer and use it in GitHub Desktop.
# Proposed benefits:
# * more verbose, but you can see more clearly all the "stuff" your method is using
# * easier to re-use methods, since they're not coupled to instance var names
# * less room for concurrency issues, since all state transforms would be in the top methods
class User
def gender
infer_gender
@gender
end
private
def infer_gender
@gender ||= if male_name?
'male'
elsif female_name?
'female'
else
'unknown'
end
end
def male_name?
@name == 'bob'
end
def female_name?
@name == 'jane'
end
end
vs
class User
def gender
@gender ||= infer_gender(@name)
end
private
def infer_gender(name)
if male_name?(name)
'male'
elsif female_name?(name)
'female'
else
'unknown'
end
end
def male_name?(name)
name == 'bob'
end
def female_name?(name)
name == 'jane'
end
end
Proposed benefits:
/ * more verbose, but you can see more clearly all the "stuff" your method is using
/ * easier to re-use partials/helpers, since they're not coupled to instance var names
/ * easy to tell what data you need loaded to be able to use a helper/partial
/ top_file.html.haml
= render :partial => 'user'
/ _user.html.haml
= user_full_name_markup
= render :partial => 'user_friend'
/ _user_friend.html.haml
= @friend.name
def user_full_name_markup
<em>@user.last_name, @user.first_name</em>
end
vs
/ top_file.html.haml
render :partial => 'user', :locals => { :user => @user, :friend => @friend }
/ _user.html.haml
= user_full_name_markup(user)
= render :partial => 'user_friend', :locals => { :friend => friend }
/ _user_friend.html.haml
= friend.name
def user_full_name_markup(user)
<em>user.last_name, user.first_name</em>
end
# Proposed benefits:
# * more verbose, but you can see more clearly all the "stuff" your method is using
# * easier to re-use methods, since they're not coupled to instance var names
class UsersController < ApplicationController
def update
load_user
check_if_user_now_active
end
private
def load_user
@user = User.find(params[:user_id])
end
def check_if_user_now_active
flash.add(:info, "active") if @user.active?
end
end
vs
class UsersController < ApplicationController
def update
@user = load_user
check_if_user_now_active(@user, flash)
end
private
def load_user(params)
User.find(params[:user_id])
end
def check_if_user_now_active(user, flash)
flash.add(:info, "active") if user.active?
end
end
@mikegehard
Copy link

Just to be clear...the second of the two examples in each group is the functional example?

I like it since it is explicit what information your methods/partials are using.

@danielhopkins
Copy link

Very nice, couple small things:

  1. Ln #40 I believe has a typo, the @ in the method sig
  2. Is ||= an atomic operation? I thought it wasn't (at least on JRuby) which means you could still have thread safety issues.

@richievos
Copy link
Author

@msgehard, correct, 2nd is the functionalish one

@danielhopkins
1: fixed, thanks

2: yeah, that was a weak argument for it, especially without adding more context. What I meant is that the only thing that cares about concurrency is the public method, at the top of the call stack, since it's the only thing interacting with state. It would of course need some form of a lock around reading/setting the value(s).

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