3

Found this in a current project:

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

Usually I use simple VALID_VIDEO_HOSTS = %w(...) and haven't any guess why the previous developers used ||=

Anybody know what are the benefits?

UPDATE

I know what does ||= in general cases, the question is mostly about defining constant that way in the model.

Ivan Linko
  • 926
  • 7
  • 15
  • 1
    I've not seen that with a constant before. Generally, the pattern for constants is `unless defined? CONSTANT_NAME`, as this answer shows http://stackoverflow.com/a/10172072/335847. – iain Apr 17 '13 at 21:44

5 Answers5

4

||= is used as a cheap way to memoize the value, as the other posters mention. However...

Why memoize a constant?

The author is most likely protecting against warnings when loading that source file multiple times. (warning: already initialized constant VALID_VIDEO_HOSTS)

Nevir
  • 7,333
  • 3
  • 36
  • 49
2

||= memoizes the value -- it sets the value only once -- only if it's not previously defined. When called subsequently, the value is already set and will not be modified. It uses Ruby's lazy loading to evaluate if the left-hand side as a boolean value, and only does the assignment if it is nil or false.

These two lines are equivalent:

  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

This is often used for memoizing (caching) if the right-hand-side is an expensive / time-consuming operation, or in general during initializations which have to be done only once.

Why ||= when assigning to a Constant?

Constants should only initialized once, and will at least issue a warning when you try to override them. The ||= makes sure the value is assigned only once to the constant. This way you don't get a warning that the constant is already initialized.

Tilo
  • 31,645
  • 4
  • 72
  • 101
1

That call that a memoize - means you set it once, and then keep that value, like a lazy load of the value.

ActiveSupport has a method for this now that works slightly differently than ||=: http://apidock.com/rails/ActiveSupport/memoize

Andrew Kuklewicz
  • 10,291
  • 1
  • 31
  • 42
0

It's used for lazily initializating a value. In your example there's not much call for it because the overhead of creating the string array is not that much. A better example would be:

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
Richard Nienaber
  • 9,247
  • 5
  • 49
  • 61
0

I personally use it in a project to allow user to load code. User code may override that constant if user desires. So I avoid error.

akostadinov
  • 15,093
  • 5
  • 64
  • 79