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
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
Thanks. I understand it now.
On 21/04/2012, at 1:15 PM, Soichi I. wrote:
@current_cart ||= Cart.find(session[:cart_id])
is equivalent to
@current_cart = if @current_cart.nil?
Cart.find(session[:cart_id])
else
@current_cart
end
Henry
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
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”
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 R.
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:
end
–
Posted via http://www.ruby-forum.com/.
–
Florian G.
smtp: [email protected]
jabber: [email protected]
gpg: 533148E2
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 Sat, Apr 21, 2012 at 8:22 PM, David H. [email protected]
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.
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
W dniu 21 kwietnia 2012 14:39 użytkownik Peter Z.
[email protected] 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 R.