What does ||= (or-equals) mean in Ruby?

前端 未结 23 2922
情书的邮戳
情书的邮戳 2020-11-21 23:20

What does the following code mean in Ruby?

||=

Does it have any meaning or reason for the syntax?

相关标签:
23条回答
  • 2020-11-21 23:31

    unless x x = y end

    unless x has a value (it's not nil or false), set it equal to y

    is equivalent to

    x ||= y

    0 讨论(0)
  • 2020-11-21 23:31

    Please also remember that ||= isn't an atomic operation and so, it isn't thread safe. As rule of thumb, don't use it for class methods.

    0 讨论(0)
  • 2020-11-21 23:32

    a ||= b is a conditional assignment operator. It means if a is undefined or falsey, then evaluate b and set a to the result. Equivalently, if a is defined and evaluates to truthy, then b is not evaluated, and no assignment takes place. For example:

    a ||= nil # => nil
    a ||= 0 # => 0
    a ||= 2 # => 0
    
    foo = false # => false
    foo ||= true # => true
    foo ||= false # => true
    

    Confusingly, it looks similar to other assignment operators (such as +=), but behaves differently.

    • a += b translates to a = a + b
    • a ||= b roughly translates to a || a = b

    It is a near-shorthand for a || a = b. The difference is that, when a is undefined, a || a = b would raise NameError, whereas a ||= b sets a to b. This distinction is unimportant if a and b are both local variables, but is significant if either is a getter/setter method of a class.

    Further reading:

    • http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html
    0 讨论(0)
  • 2020-11-21 23:36

    Concise and complete answer

    a ||= b
    

    evaluates the same way as each of the following lines

    a || a = b
    a ? a : a = b
    if a then a else a = b end
    

    -

    On the other hand,

    a = a || b
    

    evaluates the same way as each of the following lines

    a = a ? a : b
    if a then a = a else a = b end
    

    -

    Edit: As AJedi32 pointed out in the comments, this only holds true if: 1. a is a defined variable. 2. Evaluating a one time and two times does not result in a difference in program or system state.

    0 讨论(0)
  • 2020-11-21 23:37
    x ||= y
    

    is

    x || x = y
    

    "if x is false or undefined, then x point to y"

    0 讨论(0)
  • 2020-11-21 23:40

    It means or-equals to. It checks to see if the value on the left is defined, then use that. If it's not, use the value on the right. You can use it in Rails to cache instance variables in models.

    A quick Rails-based example, where we create a function to fetch the currently logged in user:

    class User > ActiveRecord::Base
    
      def current_user
        @current_user ||= User.find_by_id(session[:user_id])
      end
    
    end
    

    It checks to see if the @current_user instance variable is set. If it is, it will return it, thereby saving a database call. If it's not set however, we make the call and then set the @current_user variable to that. It's a really simple caching technique but is great for when you're fetching the same instance variable across the application multiple times.

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