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

后端 未结 3 615
臣服心动
臣服心动 2020-12-30 04:32

Should I use if defined?

 return @current_user_session if defined?(@current_user_session)
 @current_user_session = UserSession.find
相关标签:
3条回答
  • 2020-12-30 04:45

    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
    
    0 讨论(0)
  • 2020-12-30 04:49

    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.

    0 讨论(0)
  • 2020-12-30 04:50

    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.

    0 讨论(0)
提交回复
热议问题