0

I'm looking over someone's codes and wondering about the difference between:

def blah
  @hello ||= [1,2,3].collect{|x| x+1}
end

and

def blah 
  @hello = [1,2,3].collect{|x| x+1}
end

I understand that ||= means "or equal", but why do we need it? An example would be great.

Also, for the collect method, let's say I have an array:

a = [1,2,4,5]

and I wanted to find the array that contains integers that are greater than 2, how can I use collect with that?

a.collect{|x| x>2} # => [false, false, true, true]

I want [4,5].

sawa
  • 165,429
  • 45
  • 277
  • 381
user2393426
  • 165
  • 1
  • 10

4 Answers4

1

a = [1,2,4,5] and I wanted to find the array that contains integers that are greater than 2,

Here we go using Array#select:

 a.select{|e| e > 2 } # => [4,5]

Explanation of the part @hello ||= [1,2,3].collect{|x| x+1} can be found What does ||= (or equals) mean in Ruby?

Community
  • 1
  • 1
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
1

||= does nothing if the variable has been assigned a value (other than false or nil):

irb(main):001:0> blah ||= 'foo'
=> "foo"
irb(main):002:0> blah ||= 'bar'
=> "foo"
irb(main):003:0> puts blah
foo
=> nil
irb(main):004:0> blah = nil
=> nil
irb(main):005:0> blah ||= 'bar'
=> "bar"
irb(main):006:0> puts blah
bar
=> nil

One possible use is to assign variables in a fault-tolerant way. Compare:

@data = get_data_from_some_source
@data ||= get_data_from_fallback_source
@data ||= get_data_from_last_resort_source

with:

@data = get_data_from_some_souce
if @data == nil
  @data = get_data_from_fallback_source
end
if @data == nil
  @data = get_data_from_last_resort_source
end

or even (saints preserve us):

begin
  @data = get_data_from_some_source
rescue GettingDataDidntWorkException
  begin
    @data = get_data_from_fallback_source
  rescue GettingDataDidntWorkException
    @data = get_data_from_last_resort_source
  end
end

Haskell programmers will recognize this as similar in use to the Maybe monad.

Alex Hammel
  • 345
  • 1
  • 8
0

The page What does ||= (or-equals) mean in Ruby? does not mention the "proxy design pattern", which it is in a nutshell.

The first time you call that line, the .select stuff gets evaluated. The second time, the system re-uses the @hello value, without re-assigning it. Due to "boolean short-circuiting", things to the right of a || don't evaluate, if the left side is not false or nil.

(Also, if you never evaluated @hello before, Ruby automagically creates one, and assigns nil to it. So Ruby lets you proxy in one line, as an optimization.)

Community
  • 1
  • 1
Phlip
  • 5,253
  • 5
  • 32
  • 48
0

Ok, so ||= means if you already have a previous value for your variable it will keep it else, if it doesn't have any pre-assigned value, then it will take whatever value you set it equal to.

EX:

@hello = [1]

def blah
  @hello ||=[1,2,3]
end

blah 

@hello => [1], not [1,2,3]
CDub
  • 13,146
  • 4
  • 51
  • 68
user2393426
  • 165
  • 1
  • 10