In Ruby, should I use ||= or if defined? for memoization?

可紊 提交于 2019-11-30 06:43:22

Be careful: x ||= y assigns x = y if x returns false. That may mean that x is undefined, nil, or false.

There are many times variables will be defined and false, though perhaps not in the context of the @current_user_session instance variable.

If you desire conciseness, try the conditional construct:

defined?(@current_user_session) ?
    @current_user_session : @current_user_session = UserSession.find

or just:

defined?(@current_user_session) || @current_user_session = UserSession.find

if you just need to initialize the variable.

mwilliams

Rails does have memoization, check out the screencast below for a great introduction:

http://railscasts.com/episodes/137-memoization

class Product < ActiveRecord::Base
  extend ActiveSupport::Memoizable

  belongs_to :category

  def filesize(num = 1)
    # some expensive operation
    sleep 2
    12345789 * num
  end

  memoize :filesize
end

Additionally, the nicer ||= produces a warning (on 1.8.6 and 1.8.7, at least) about uninitialized instance variables, while the more verbose defined? version does not.

On the other hand, this probably does what you want:

def initialize
  @foo = nil
end

def foo
  @foo ||= some_long_calculation_for_a_foo
end

But this almost certainly does not:

def initialize
  @foo = nil
end

def foo
  return @foo if defined?(@foo)
  @foo = some_long_calculation_for_a_foo
end

since @foo will always be defined at that point.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!