Ruby 3.4, No More TypeError With **nil As It Is Treated As An Empty Hash.

In Ruby, the splat * and double splat ** operators are used for handling variable-length arguments in methods, especially when dealing with arrays and hashes.

The Single Splat operator (*) constructs and spreads out Arrays.

If we use it when defining a method, it constructs into an array.

def example_method(*args)
  puts "args are: #{args}"
end

example_method(3, 5, 7) 

# => args are: [3, 5, 7]

If we use it when passing arguments as an array, it deconstructs the array into arguments.

def example_method(a, b, c)
  puts "args are: #{a}, #{b}, #{c}"
end

example_method(*[3, 5, 7]) 

# => args are: 3, 5, 7

The double Splat operator (**) It works similarly. We can construct and spread out Hashes.

If we use it when defining a method, it constructs into an hash.

def example_method(**args)
  puts "args are: #{args}"
end

options = {x: 1, y: 2}

example_method(**options) 

# => args are: {:x=>1, :y=>2}

If we use it when passing arguments as an hash, it deconstructs the hash into arguments.

def example_method(a:, b:, c:)
  puts "args are: #{a}, #{b}, #{c}"
end

hash = { a: 1, b: 2, c: 3 }

example_method(**hash)

# => args are: 1, 2, 3

Before

When we use the splat operator * and double splat operator ** with nil, they have specific behaviors.

When splat * operator used with nil, it essentially treats nil as an empty array.

def example_method(*args)
  puts "args are: #{args}"
end

example_method(*nil)

# => args are: []

When double splat ** operator used with nil, it raises an error because nil cannot be implicitly converted into a hash.

def example_method(**args)
  puts "args are: #{args}"
end

example_method(**nil)

# => no implicit conversion of nil into Hash (TypeError)

After

Ruby 3.4 fixes this inconsistent behavior between array splat *nil and hash splat **nil with this PR by not raising any error with **nil.

When **nil is used, it is treated similarly to **{}, which passes no keywords and does not call any conversion methods.

def example_method(**args)
  puts "args are: #{args}"
end

example_method(**nil)

# => args are: {}

Need help on your Ruby on Rails or React project?

Join Our Newsletter