26 June 2009

don't forget the parenthesis!

>> nil || 1
=> 1

Category.find :first, :conditions => "permalink='education'" || 1
=> nil

It took me a while - 10 min! - to understand that ruby could not understand my super lean code with no parenthesis. What I wanted to express is something like:

>> (Category.find :first, :conditions => "permalink='education'") || 1
=> 1

Aside from this misunderstanding from my part, ruby is such an efficient language and I would have serious problems to come back to languages with heavy syntax such as java!

04 June 2009

Before | After

Before:



def self.find_expiring_soon(date_time = Time.now)
@@expiring_soon ||= find(:all, :conditions => ["type_id = 1 AND completed = 0 AND created_at < :date", { :date => (4.months + 14.days).ago(date_time) }])
end

def self.find_expiring_soon_with_donations(date_time = Time.now)
@@expiring_soon_with_donations ||= find(:all, :conditions => ["type_id = 1 AND completed = 0 AND donated_amount > 0 AND created_at < :date", { :date => (4.months + 14.days).ago(date_time) }])
end

def self.find_expiring_soon_without_donations(date_time = Time.now)
@@expiring_soon_with_donations ||= find(:all, :conditions => ["type_id = 1 AND completed = 0 AND donated_amount = 0 AND created_at < :date", { :date => (4.months + 14.days).ago(date_time) }])
end

def self.find_expiring_very_soon(date_time = Time.now)
@@expiring_very_soon ||= find(:all, :conditions => ["type_id = 1 AND completed = 0 AND created_at < :date", { :date => (6.months - 3.days).ago(date_time) }])
end



After:



def self.find_expiring_soon_with_donations
find(:all,
:include => :donations,
:conditions => [
"expires_soon = 0
#{with_expiring_criterias}
AND donated_amount > 0", { :date => four_months_and_a_half_ago }])
end

def self.find_expiring_soon_without_donations
find(:all,
:conditions => [
"expires_soon = 0
#{with_expiring_criterias}
AND donated_amount = 0", { :date => four_months_and_a_half_ago }])
end

def self.find_expiring_very_soon
find(:all,
:conditions => [
"expires_very_soon = 0
#{with_expiring_criterias}
", { :date => (6.months - 3.days).ago(date_time) }])
end

def self.find_expiring_now
find(:all,
:conditions => [
"expired = 0
#{with_expiring_criterias}", { :date => 6.months.ago }])
end

def self.with_expiring_criterias # DRY
"AND type_id = #{ElementType::MONEY}
AND completed = 0
AND activated_at < :date" end

private_class_method :with_expiring_criterias

def self.four_months_and_a_half_ago
@@FOUR_MONTHS_AND_A_HALF_AGO ||= (6.months - 6.weeks).ago(Time.now)
end

private_class_method :four_months_and_a_half_ago


  • Much more lines of code (LOC), does it improve readability and understading?
  • hardcoded values replaced by objects (ElementType::MONEY), does it make easier to understand the meaning of numbers without knowing the DB model
  • duplicate SQL DRyed in a private method
Which version do you prefer?

30 April 2009

Unix recursive Find and Replace

find spec ! -regex ".*.svn.*" -type f -exec grep -l "it_should_behave_like" {} \; | xargs sed -i "" "s/it_should_behave_like/#it_should_behave_like/"

Explanation:
  • find spec find in ./spec folfer
  • ! -regex ".*.svn.*" excluding .svn folders
  • -type f only files
  • -exec grep -l "it_should_behave_like" {} \; extra line to grep only files which contain "it_should_behave_like"
  • | xargs sed -i "" pipe to sed editor without creating any backup file (-i)
  • "s/ENTER OLD STRING OR TEXT TO REPLACE/ENTER REPLACEMENT STRING OR TEXT/"

21 croissants' Blog