%w(hashrockets spaceships bangbangs)

> non-optimized bits & pieces <

Flexible Method Arguments With the Splat Operator

The splat operator allows a method to accepts 0 ~ ruby’s max number (hm, i don’t know what number is that) of arguments, this makes it super flexible, & here are some ways to take advantage of that:

1) Probably simple flat list

1
2
3
4
5
6
7
8
9
10
11
12
13
def mm(*args)
  args.each_with_index {|arg, i| puts "A[#{i}]: #{arg}" }
end

mm
# >> (blank)

mm(1)
# >> A[0]: 1

mm(1, 2)
# >> A[0]: 1
# >> A[1]: 2

2) May have array & must be flattened

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def mm(*args)
  [args].flatten.each_with_index {|arg, i| puts "A[#{i}]: #{arg}" }
end

mm
# >> (blank)

mm(1) # same as mm([1])
# >> A[0]: 1

mm([1, 2]) # same as mm([1], [2]), mm(1, [2]) & mm([1], 2)
# >> A[0]: 1
# >> A[1]: 2

mm(1, [2, 3]) # same as mm([1, 2, 3]), mm([1], [2, 3]), etc
# >> A[0]: 1
# >> A[1]: 2
# >> A[2]: 3

3) May want to support options-like usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def mm(*args)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  args.each_with_index {|arg, i| puts "A[#{i}]: #{arg}" }
  opts.each {|key, val| puts "O[#{key}]: #{val}" }
end

mm
# >> (blank)

mm(x:1)
# >> O[x]: 1

mm(1)
# >> A[0]: 1

mm(1, x:2)
# >> A[0]: 1
# >> O[x]: 2

mm(1, 2, x:3, y:4)
# >> A[0]: 1
# >> A[1]: 2
# >> O[x]: 3
# >> O[y]: 4

4) May want to passing in a code-block

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def mm(*args, &block)
  args.each_with_index {|arg, i| puts "A[#{i}]: #{arg}" }
  puts block.call if block_given?
end

mm
# >> (blank)

mm { "B[*]: rocks" }
# >> B[*]: rocks

mm(1) { "B[*]: rocks" }
# >> A[0]: 1
# >> B[*]: rocks

mm(1, 2) { "B[*]: rocks" }
# >> A[0]: 1
# >> A[1]: 2
# >> B[*]: rocks

5) All in one

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def mm(*args, &block)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  [args].flatten.each_with_index {|arg, i| puts "A[#{i}]: #{arg}" }
  opts.each {|key, val| puts "O[#{key}]: #{val}" }
  puts block.call if block_given?
end

mm(1, [2, 3], x:4, y:5) { "B[*]: rocks" }
# >> O[x]: 4
# >> O[y]: 5
# >> A[0]: 1
# >> A[1]: 2
# >> A[2]: 3
# >> O[x]: 4
# >> O[y]: 5
# >> B[*]: rocks

Extra Reading

To advance ur ruby kungfu, you probably want some extra reading from the free chapter abt designing beautiful apis, from Ruby Best Practices.

ruby, tips

Comments