代码之家  ›  专栏  ›  技术社区  ›  Kris

在Ruby中,我应该使用还是定义后使用?为了记忆?

  •  14
  • Kris  · 技术社区  · 17 年前

    我应该用吗? if defined?

     return @current_user_session if defined?(@current_user_session)
     @current_user_session = UserSession.find
    

    ||=

    @current_user_session ||= UserSession.find
    

    我注意到了 如果定义? 方法的使用越来越近。一个比另一个有什么优势吗?我个人比较喜欢 = 为了可读性。我也认为Rails可能有 memoize 透明地提供此行为的宏。是这样吗?

    3 回复  |  直到 11 年前
        1
  •  25
  •   guns    17 年前

    小心:如果x返回false,x=y将分配x=y。这可能意味着x是未定义的、零或假。

    变量将被定义并设置为false的次数很多,尽管可能不在@current_user_session实例变量的上下文中。

    如果您希望简洁,请尝试条件构造:

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

    或者只是:

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

    如果只需要初始化变量。

        2
  •  1
  •   Kris    11 年前

    Rails确实有记忆功能,请查看下面的屏幕广播了解详细介绍:

    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
    
        3
  •  0
  •   James A. Rosen    17 年前

    另外,更好的 ||= 生成有关未初始化实例变量的警告(至少在1.8.6和1.8.7上),但越详细 defined? 版本没有。

    另一方面,这可能满足您的需求:

    def initialize
      @foo = nil
    end
    
    def foo
      @foo ||= some_long_calculation_for_a_foo
    end
    

    但这几乎肯定不会:

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

    自从 @foo 总是 在那一点上被定义。

    推荐文章