Skip to content

Instantly share code, notes, and snippets.

@jamesyang124
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesyang124/a4e1ce1c1e3003fb7a2e to your computer and use it in GitHub Desktop.
Save jamesyang124/a4e1ce1c1e3003fb7a2e to your computer and use it in GitHub Desktop.
&&= or ||= or * in Ruby

Initialization with AND or OR operators:

and, or, not have lower precedece and short-circulating proeperty. Treat them as control-flow modifier.

foo = 42 && foo / 2 
# error because it transalte to: foo = (42 && foo) / 2
   
foo = 42 and foo / 2
# assign foo to 42 then divide by 2.
a ||= "x"           # => a = "x"
a ||= "s"           # => a = "x"


b &&= "s"           # => b = nil
b = "x"
b &&= "s"           # => b = "s"

#Same output in Javascript

"string" && "last"  # => "last"
"string" || "last"  # => "string"

nil && "string"     # => nil
nil & "string"      # => false
5 & 7               # => 5

nil || "string"     # => "string"
nil | "string"      # => true
5 | 7               # => 7

Splat operator:

#Splat operator

#The split mode:
pet1, pet2, pet3 = *["duck","dog","cat"]

#The collect mode:
  *zoo = pet1, pet2, pet3
  
[1, 2, 3].find do |*a|
 puts "a #{a}"
end
# a [1]
# a [2]
# a [3]

def x(*args)
 args.find do |*x| # In here, x splated to collect mode, so convert to an array. 
   yield x  # In here, x splated to collect mode, so convert to an element. 
 end
end

x(1, 3, 5) { |e| puts "e #{e}" }
# e [1]
# e [3]
# e [5]

def x(*args)
 args.find do |*x| # In here, x splated to collect mode, so convert to an array. 
   yield *x  # In here, x splated to split mode, convert to an element. 
 end
end

x(1, 3, 5) { |e| puts "e #{e}" }
# e 1
# e 3
# e 5

Splat operator

def a(a, *ary)
 a.push(*ary)
 p *ary.shift
 yield(a, *ary)
end

a = [1,2,3] 
b, c, d = a
p b
# 1

# use splator to iterate all elements and insert to array.
[5, *a]
# [5, 1, 2, 3]
[5, a]
# [5, 1, 2, 3]

# three ways have same result.
a([],"Hello", "H", "H") do |x, *args|
 x.send(:count, *args)
end
a([],"Hello", "H", "H", &lambda{ |x, *args| x.send(:count), *args})
a([],"Hello", "H", "H", &:count)
 
 
# same result
some_method do |foo, *args|
  foo.swizzle(*args)
end
some_method(:swizzle)
 
class Symbol
 def to_proc
  lambda{ |x, *args| x.send(self, *args)}
 end
end 
[1,2,3].map(&:upcase)
 

Proc with multiple arguments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment