在Ruby中,我应该使用|| =还是定义?记忆?

时间:2009-06-08 08:16:41

标签: ruby-on-rails ruby memoization

我应该使用if defined?

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

||=

@current_user_session ||= UserSession.find

我注意到最近越来越多地使用if defined?方法。一个人对另一个人有什么好处吗?就个人而言,我更喜欢||=的可读性。我也认为Rails可能有一个memoize宏,它可以透明地提供这种行为。是这种情况吗?

3 个答案:

答案 0 :(得分:25)

注意:如果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

如果您只需要初始化变量。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

此外,更好的||=会产生关于未初始化的实例变量的警告(至少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 总是在那时定义