【问题标题】:What is the reason to use ||= instead of = in model to define a constant在模型中使用 ||= 而不是 = 来定义常量的原因是什么
【发布时间】:2013-04-17 21:42:20
【问题描述】:

在当前项目中找到这个:

class Video < ActiveRecord::Base
  ...
  VALID_VIDEO_HOSTS ||= %w(www.youtube.com youtube.com vimeo.com www.vimeo.com)
  ...
end

通常我使用简单的 VALID_VIDEO_HOSTS = %w(...) 并且没有任何猜测为什么以前的开发人员使用 ||=

有人知道有什么好处吗?

更新

我知道 ||= 在一般情况下是什么,问题主要是关于在模型中以这种方式定义常量。

【问题讨论】:

标签: ruby-on-rails ruby


【解决方案1】:

||= 被用作memoize the value 的廉价方式,正如其他海报所提到的那样。不过……

为什么要记住一个常量?

作者很可能在多次加载该源文件时防止出现警告。 (warning: already initialized constant VALID_VIDEO_HOSTS)

【讨论】:

    【解决方案2】:

    ||= 记忆值 -- 它只设置一次值 -- 仅在之前未定义的情况下。随后调用时,该值已设置,不会被修改。它使用 Ruby 的延迟加载来评估左侧是否为布尔值,并且仅当它为 nil 或 false 时才进行赋值。

    这两行是等价的:

      var ||= something
    
      var = something if var.nil?   # this is equivalent to ||=
    
      # Note: memoizing with ||= only works if the right-hand side is not a boolean function;
      #       because if it's value would be false, it could not use Ruby's lazy-loading
    

    这通常用于memoizing(缓存),如果右侧是一项昂贵/耗时的操作,或者通常在只需要执行一次的初始化期间。

    为什么在赋值给常量时 ||=?

    常量应该只初始化一次,并且在你尝试覆盖它们时至少会发出警告。 ||= 确保该值只分配给常量一次。这样您就不会收到常量已初始化的警告。

    【讨论】:

    • 它们相同。想想var == false时的情况
    • 确实如此。你不能用 ||= 记住布尔函数 :)
    • 你可以,只是不使用那种语法。 if defined? val 可用于记忆假值
    【解决方案3】:

    所谓的 memoize - 意味着您设置一次,然后保留该值,就像值的延迟加载一样。

    ActiveSupport 现在有一个方法,它的工作方式与||= 略有不同: http://apidock.com/rails/ActiveSupport/memoize

    【讨论】:

      【解决方案4】:

      它用于延迟初始化一个值。在您的示例中,没有太多要求,因为创建字符串数组的开销并不多。一个更好的例子是:

      class WebsiteImageHelper
          def get_image_files
            #recurse directories looking for images
            #this will only happen once per instance of 
            #WebsiteImageHelper
            @image_files ||= Dir['images/**/**']
          end
      end
      

      【讨论】:

        【解决方案5】:

        我个人在一个项目中使用它来允许用户加载代码。如果用户愿意,用户代码可以覆盖该常量。所以我避免了错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-17
          • 1970-01-01
          • 1970-01-01
          • 2011-09-12
          • 2012-06-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多