+ All Categories
Home > Technology > Date Once

Date Once

Date post: 21-Jan-2015
Category:
Upload: mike-bowler
View: 865 times
Download: 1 times
Share this document with a friend
Description:
Explanation of the method Date::once in the ruby core classes. This talk was originally given at the TSOT Ruby on Rails Project Night
Popular Tags:
27
Inside Date.once Understanding some of the more interesting code in the Ruby core
Transcript
Page 1: Date Once

Inside Date.once Understanding some of the more interesting

code in the Ruby core

Page 2: Date Once

The Problem

Page 3: Date Once

The Problem

Instances of Date are immutable

Page 4: Date Once

The Problem

Instances of Date are immutable

Many methods involve complex calculations

Page 5: Date Once

The Problem

Instances of Date are immutable

Many methods involve complex calculations

Caching of results is desirable

Page 6: Date Once

The Problem

Instances of Date are immutable

Many methods involve complex calculations

Caching of results is desirable

Want to keep the code clean and uncluttered with caching related code

Page 7: Date Once

def jd_to_civil(jd, sg=GREGORIAN) if os?(jd, sg) a = jd else x = ((jd - 1867216.25) / 36524.25).floor a = jd + 1 + x - (x / 4.0).floor end b = a + 1524 c = ((b - 122.1) / 365.25).floor d = (365.25 * c).floor e = ((b - d) / 30.6001).floor dom = b - d - (30.6001 * e).floor if e <= 13 m = e - 1 y = c - 4716 else m = e - 13 y = c - 4715 end return y, m, domend

Page 8: Date Once

The Solution

Page 9: Date Once

The Solution

Write the individual methods as if they would not be cached

Page 10: Date Once

The Solution

Write the individual methods as if they would not be cached

Use some meta-programming magic to add caching support after the fact

def jd_to_civil ...end

once :jd_to_civil

Page 11: Date Once

class << self def once(*ids) # :nodoc: for id in ids module_eval <<-"end;", __FILE__, __LINE__ alias_method :__#{id.to_i}__, :#{id.to_s} private :__#{id.to_i}__ def #{id.to_s}(*args, &block) if defined? @__#{id.to_i}__ @__#{id.to_i}__ elsif ! self.frozen? @__#{id.to_i}__ ||= __#{id.to_i}__(*args, &block) else __#{id.to_i}__(*args, &block) end end end; end end

private :onceend

Page 12: Date Once

class << self def once(*ids) # :nodoc: for id in ids module_eval <<-"end;", __FILE__, __LINE__ alias_method :__#{id.to_i}__, :#{id.to_s} private :__#{id.to_i}__ def #{id.to_s}(*args, &block) if defined? @__#{id.to_i}__ @__#{id.to_i}__ elsif ! self.frozen? @__#{id.to_i}__ ||= __#{id.to_i}__(*args, &block) else __#{id.to_i}__(*args, &block) end end end; end end

private :onceend

Page 13: Date Once

class << self def once(*ids) # :nodoc: for id in ids module_eval <<-"end;", __FILE__, __LINE__ alias_method :__#{id.to_i}__, :#{id.to_s} private :__#{id.to_i}__ def #{id.to_s}(*args, &block) if defined? @__#{id.to_i}__ @__#{id.to_i}__ elsif ! self.frozen? @__#{id.to_i}__ ||= __#{id.to_i}__(*args, &block) else __#{id.to_i}__(*args, &block) end end end; end end

private :onceend

Page 14: Date Once

alias_method :__14369__, :jd_to_civilprivate :__14369__def jd_to_civil(*args, &block) if defined? @__14369__ @__14369__ elsif ! self.frozen? @__14369__ ||= __14369__(*args, &block) else __14369__(*args, &block) endend

once :jd_to_civil

Page 15: Date Once

alias_method :__14369__, :jd_to_civilprivate :__14369__def jd_to_civil(*args, &block) if defined? @__14369__ @__14369__ elsif ! self.frozen? @__14369__ ||= __14369__(*args, &block) else __14369__(*args, &block) endend

once :jd_to_civil

Page 16: Date Once

alias_method

puts 'cat'

class Example

def one

puts 'cat'

end

end

one

Message

class Example

Page 17: Date Once

alias_methodclass Example

def one

puts 'cat'

end

alias_method :two, :one

endputs 'cat'

two

one

Message

class Example

Page 18: Date Once

alias_methodclass Example

def one

puts 'cat'

end

alias_method :two, :one

def one

puts 'dog'

end

end

puts 'cat'twoone

Message

class Example

puts 'dog'

Page 19: Date Once

alias_method :__14369__, :jd_to_civilprivate :__14369__def jd_to_civil(*args, &block) if defined? @__14369__ @__14369__ elsif ! self.frozen? @__14369__ ||= __14369__(*args, &block) else __14369__(*args, &block) endend

once :jd_to_civil

Page 20: Date Once

alias_method :__14369__, :jd_to_civilprivate :__14369__def jd_to_civil(*args, &block) if defined? @__14369__ @__14369__ elsif ! self.frozen? @__14369__ ||= __14369__(*args, &block) else __14369__(*args, &block) endend

once :jd_to_civil

Page 21: Date Once

alias_method :__14369__, :jd_to_civilprivate :__14369__def jd_to_civil(*args, &block) if defined? @__14369__ @__14369__ elsif ! self.frozen? @__14369__ ||= __14369__(*args, &block) else __14369__(*args, &block) endend

once :jd_to_civil

Page 22: Date Once

alias_method :__14369__, :jd_to_civilprivate :__14369__def jd_to_civil(*args, &block) if defined? @__14369__ @__14369__ elsif ! self.frozen? @__14369__ ||= __14369__(*args, &block) else __14369__(*args, &block) endend

once :jd_to_civil

Page 23: Date Once

Frozen objects

Object.freeze

“Prevents further modifications to obj. A TypeError will be raised if modification is attempted. There is no way to unfreeze a frozen object.”

Object.frozen?

“Returns the freeze status of obj“

Page 24: Date Once

alias_method :__14369__, :jd_to_civilprivate :__14369__def jd_to_civil(*args, &block) if defined? @__14369__ @__14369__ elsif ! self.frozen? @__14369__ ||= __14369__(*args, &block) else __14369__(*args, &block) endend

once :jd_to_civil

Page 25: Date Once

alias_method :__14369__, :jd_to_civilprivate :__14369__def jd_to_civil(*args, &block) if defined? @__14369__ @__14369__ elsif ! self.frozen? @__14369__ ||= __14369__(*args, &block) else __14369__(*args, &block) endend

once :jd_to_civil

Page 26: Date Once

class << self def once(*ids) # :nodoc: for id in ids module_eval <<-"end;", __FILE__, __LINE__ alias_method :__#{id.to_i}__, :#{id.to_s} private :__#{id.to_i}__ def #{id.to_s}(*args, &block) if defined? @__#{id.to_i}__ @__#{id.to_i}__ elsif ! self.frozen? @__#{id.to_i}__ ||= __#{id.to_i}__(*args, &block) else __#{id.to_i}__(*args, &block) end end end; end end

private :onceend

Page 27: Date Once

Shameless Plug

I can help you with your Ruby and/or Rails projects. Ask me how.

Mike [email protected] (company)www.SphericalImprovement.com (blog)


Recommended