Ruby double splat (**) operator cheatsheet
The operator ** is useful as an options hash.
def one_method(**options);end
This form is completely similar to the following:
def another_method(options = {});end
In addition, you can strictly define the set of required keys for the method.
def one_strict_method(first_name:, last_name: , **options) puts "options: #{options}" greeting = "Hello #{first_name} #{last_name}" puts options[:upcase] ? greeting.upcase : greeting end
pry(main)> one_strict_method(upcase: true) ArgumentError: missing keywords: first_name, last_name pry(main)> one_strict_method(first_name: 'John', last_name: 'Doe', upcase: true) options: {:upcase=>true} HELLO JOHN DOE => nil
Another advantage of double splat literal is that it works like #merge for Ruby Hash
class Contact::ShowRepresenter #:nodoc: def call(contact) { contact: { **base_info(contact), **legal_info(contact), # You can add something more complex here. # **GeoLocaionRepresenter.new.(contact) } } end private def base_info(contact) { id: contact.id, first_name: contact.first_name, last_name: contact.last_name, email: contact.email, phone: contact.phone } end def legal_info(contact) { legal_name: contact.legal_name, legal_type: contact.legal_type, mailing_address: contact.mailing_address } end end
pry(main)>Contact::ShowRepresenter.new.(Contact.last) => { :contact=>{ :id=>51986, :first_name=>"Ilia", :last_name=>"Kriachkov", :email=>"[email protected]", :phone=>"+79000000000", :legal_name=>"JetRockets", :legal_type=>"LLC", :mailing_address=>"15 Let Oktyabrya Street, #10b, Tver, Russian Federation 170008" } }
In conclusion, I want to demonstrate some benchmark results.
As you can see, the ** operator is a bit faster than Hash#merge.
require 'benchmark' n = 50_000 Benchmark.bm(2) do |x| x.report('merge: ') { n.times { merge } } x.report('double_splat_merge:') { n.times { double_splat_merge } } end def merge hash = { a: 'a' } { b: 'b' }.merge(hash) end def double_splat_merge hash = { a: 'a' } { b: 'b', **hash } end
user system total real merge: 0.109247 0.088652 0.197899 ( 0.204470) double_splat_merge: 0.079480 0.003590 0.083070 ( 0.083642)