Ruby Memoization
class User < ActiveRecord::Base
def twitter_followers
# assuming twitter_user.followers makes a network call
@twitter_followers ||= twitter_user.followers
end
end
# @twitter_followers = @twitter_followers || twitter_user.followers
For multiline
class User < ActiveRecord::Base
def main_address
@main_address ||= begin
maybe_main_address = home_address if prefers_home_address?
maybe_main_address = work_address unless maybe_main_address
maybe_main_address = addresses.first unless maybe_main_address
end
end
end
The begin...end
creates a block of code in Ruby that can be treated as a single thing, kind of like {...}
in C-style languages. That’s why ||=
works just as well here as it did before.
But there is a chance for `nil` so can use like bellow
class User < ActiveRecord::Base
def twitter_followers
return @twitter_followers if defined? @twitter_followers
@twitter_followers = twitter_user.followers
end
end
class User < ActiveRecord::Base
def main_address
return @main_address if defined? @main_address
@main_address = begin
main_address = home_address if prefers_home_address?
main_address ||= work_address
main_address ||= addresses.first # some semi-sensible default
end
end
end
https://www.justinweiss.com/articles/4-simple-memoization-patterns-in-ruby-and-one-gem/
Last updated