What does '||=' mean?

Well, as stated in the subject, what does '||=' mean?

It's from

  def current_cart
    if session[:cart_id]
      @current_cart ||= Cart.find(session[:cart_id]) #HERE!!!
      session[:cart_id] = nil if @current_cart.purchased_at
    end
    if session[:cart_id].nil?
      @current_cart = Cart.create!
      session[:cart_id] = @current_cart.id
    end
    @current_cart
  end

Is this Rails issue? I thought it's some Ruby grammar thing, because I
know there is an expression, '|='.

Thanks in advance.

soichi

···

--
Posted via http://www.ruby-forum.com/.

equivalent to

@ivar = @ivar || value

ruby || short circuits, so if @ivar is nil, then value gets assigned to
@ivar. it's referred to as a "nil guard".

see Pragmatic Bookshelf: By Developers, For Developers

···

On Fri, Apr 20, 2012 at 9:15 PM, Soichi Ishida <lists@ruby-forum.com> wrote:

Well, as stated in the subject, what does '||=' mean?

It's from

def current_cart
   if session[:cart_id]
     @current_cart ||= Cart.find(session[:cart_id]) #HERE!!!
     session[:cart_id] = nil if @current_cart.purchased_at
   end
   if session[:cart_id].nil?
     @current_cart = Cart.create!
     session[:cart_id] = @current_cart.id
   end
   @current_cart
end

Is this Rails issue? I thought it's some Ruby grammar thing, because I
know there is an expression, '|='.

Thanks in advance.

soichi

--
Posted via http://www.ruby-forum.com/\.

Thanks. I understand it now.

···

--
Posted via http://www.ruby-forum.com/.

is equivalent to

@current_cart = if @current_cart.nil?
  Cart.find(session[:cart_id])
else
  @current_cart
end

Henry

···

On 21/04/2012, at 1:15 PM, Soichi Ishida wrote:

@current_cart ||= Cart.find(session[:cart_id])

The best way of thinking of it, is that it will assign a default value
to a variable. So, if you have @var1 to initialize to a default value
when its not set already, then:

@var1 ||= "default"

···

--
Posted via http://www.ruby-forum.com/.

Ian M. Asaff писал 21.04.2012 05:20:

equivalent to

@ivar = @ivar || value

ruby || short circuits, so if @ivar is nil, then value gets assigned to
@ivar. it's referred to as a "nil guard".

see Pragmatic Bookshelf: By Developers, For Developers

The info on that link is incorrect or outdated. On recent Rubies like 1.9.3
the nil guard explicitly does not show a warning if the variable did not exist
beforehand. Check it yourself:

$ ruby -W2 -e '@ivar ||= 1'
$ ruby -W2 -e '@ivar = @ivar || 1'
-e:1: warning: instance variable @ivar not initialized

···

On Fri, Apr 20, 2012 at 9:15 PM, Soichi Ishida <lists@ruby-forum.com> > wrote:

Well, as stated in the subject, what does '||=' mean?

It's from

def current_cart
   if session[:cart_id]
     @current_cart ||= Cart.find(session[:cart_id]) #HERE!!!
     session[:cart_id] = nil if @current_cart.purchased_at
   end
   if session[:cart_id].nil?
     @current_cart = Cart.create!
     session[:cart_id] = @current_cart.id
   end
   @current_cart
end

Is this Rails issue? I thought it's some Ruby grammar thing, because I
know there is an expression, '|='.

Thanks in advance.

soichi

--
Posted via http://www.ruby-forum.com/\.

--
   WBR, Peter Zotov.

Close.

    a ||= b

Is actually equivalent to

    a || a = b

This is not as obvious in the ivar case, but combined with access like hashes, it is a bit different:

    foo[:bar] || foo[:bar] = 'batz'

is called once if :bar is present, and = is called once if :bar is not present.

While in:

    foo[:bar] = foo[:bar] || 'batz'

both and = are called, independent of the value if :bar.

···

On Apr 21, 2012, at 3:20 AM, Ian M. Asaff wrote:

equivalent to

@ivar = @ivar || value

ruby || short circuits, so if @ivar is nil, then value gets assigned to @ivar. it's referred to as a "nil guard".

see Pragmatic Bookshelf: By Developers, For Developers

On Fri, Apr 20, 2012 at 9:15 PM, Soichi Ishida <lists@ruby-forum.com> wrote:
Well, as stated in the subject, what does '||=' mean?

It's from

def current_cart
   if session[:cart_id]
     @current_cart ||= Cart.find(session[:cart_id]) #HERE!!!
     session[:cart_id] = nil if @current_cart.purchased_at
   end
   if session[:cart_id].nil?
     @current_cart = Cart.create!
     session[:cart_id] = @current_cart.id
   end
   @current_cart
end

Is this Rails issue? I thought it's some Ruby grammar thing, because I
know there is an expression, '|='.

Thanks in advance.

soichi

--
Posted via http://www.ruby-forum.com/\.

--
Florian Gilcher

smtp: flo@andersground.net
jabber: Skade@jabber.ccc.de
gpg: 533148E2

W dniu 21 kwietnia 2012 14:39 użytkownik Peter Zotov
<whitequark@whitequark.org> napisał:

The info on that link is incorrect or outdated. On recent Rubies like 1.9.3
the nil guard explicitly does not show a warning if the variable did not
exist
beforehand. Check it yourself:

$ ruby -W2 -e '@ivar ||= 1'
$ ruby -W2 -e '@ivar = @ivar || 1'
-e:1: warning: instance variable @ivar not initialized

It does warn for me in both cases. I'm running ruby 1.9.3p0
(2011-10-30) [i386-mingw32] on Windows XP SP3.

-- Matma Rex

Oh wow, a subtle distinction, but important. I did not know.

if the left hand side is non-nil then no assignment happens at all.

Thanks,
David

···

On 04/21/2012 10:44 AM, Florian Gilcher wrote:

Close.

a ||= b

Is actually equivalent to

a || a = b

This is not as obvious in the ivar case, but combined with access
like hashes, it is a bit different:

foo[:bar] || foo[:bar] = 'batz'

is called once if :bar is present, and = is called once if :bar is
not present.

While in:

foo[:bar] = foo[:bar] || 'batz'

both and = are called, independent of the value if :bar.

On Apr 21, 2012, at 3:20 AM, Ian M. Asaff wrote:

equivalent to

@ivar = @ivar || value

ruby || short circuits, so if @ivar is nil, then value gets assigned
to @ivar. it's referred to as a "nil guard".

see http://forums.pragprog.com/forums/130/topics/3644

On Fri, Apr 20, 2012 at 9:15 PM, Soichi Ishida <lists@ruby-forum.com >> <mailto:lists@ruby-forum.com>> wrote:

    Well, as stated in the subject, what does '||=' mean?

    It's from

    def current_cart
    if session[:cart_id]
    @current_cart ||= Cart.find(session[:cart_id]) #HERE!!!
    session[:cart_id] = nil if @current_cart.purchased_at
    end
    if session[:cart_id].nil?
    @current_cart = Cart.create!
    session[:cart_id] = @current_cart.id <http://current_cart.id/>
    end
    @current_cart
    end

    Is this Rails issue? I thought it's some Ruby grammar thing, because I
    know there is an expression, '|='.

    Thanks in advance.

    soichi

    --
    Posted via http://www.ruby-forum.com/\.

--
Florian Gilcher

smtp: flo@andersground.net <mailto:flo@andersground.net>
jabber: Skade@jabber.ccc.de <mailto:Skade@jabber.ccc.de>
gpg: 533148E2

Okay, it behaves like you adverties if you actually wrap that instance
variable in a class.

ruby -W2 -e "class A; def asd; @ivar ||= 1; end; end; A.new.asd"

ruby -W2 -e "class A; def asd; @ivar = @ivar || 1; end; end; A.new.asd"

-e:1: warning: instance variable @ivar not initialized

-- Matma Rex

More subtleties: if the left hand side is non falseish (i.e. not nil
and not false) the assignment will happen.

irb(main):008:0> h={:x=>false,:y=>nil}
=> {:x=>false, :y=>nil}
irb(main):009:0> h[:x] ||= 1
=> 1
irb(main):010:0> h[:y] ||= 2
=> 2
irb(main):011:0> h[:z] ||= 3
=> 3
irb(main):012:0> h
=> {:x=>1, :y=>2, :z=>3}

Note also that in case of a Hash the default value influences the result:

irb(main):016:0> h={:x=>false,:y=>nil}
=> {:x=>false, :y=>nil}
irb(main):017:0> h.default = 99
=> 99
irb(main):018:0> h[:x] ||= 1
=> 1
irb(main):019:0> h[:y] ||= 2
=> 2
irb(main):020:0> h[:z] ||= 3
=> 99
irb(main):021:0> h
=> {:x=>1, :y=>2}

And, to make things more complicated, there's also a default_proc:

irb(main):022:0> h = Hash.new {|ha,k| ha[k]=88}.merge(:x=>false,:y=>nil)
=> {:x=>false, :y=>nil}
irb(main):023:0> h[:x] ||= 1
=> 1
irb(main):024:0> h[:y] ||= 2
=> 2
irb(main):025:0> h[:z] ||= 3
=> 88
irb(main):026:0> h
=> {:x=>1, :y=>2, :z=>88}

Kind regards

robert

···

On Sat, Apr 21, 2012 at 8:22 PM, David Heitzman <rubyinfo@aptifuge.com> wrote:

Oh wow, a subtle distinction, but important. I did not know.

if the left hand side is non-nil then no assignment happens at all.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/