Skip to content

Instantly share code, notes, and snippets.

@ccyrille
Created January 28, 2022 22:00
Show Gist options
  • Save ccyrille/a93fd4eda542662e2d7192616b3ffbc3 to your computer and use it in GitHub Desktop.
Save ccyrille/a93fd4eda542662e2d7192616b3ffbc3 to your computer and use it in GitHub Desktop.
# Service module
#
# Example usage :
# ```
# class SayHello
# include Service
#
# attr_accessor :name
#
# def call
# puts "Hello #{name} !"
# end
# end
#
# SayHello.call(name: "toto")
# ```
module Service
def self.included(base)
base.class_eval do
# Proxy to #call instance method
def self.call(*args)
new(*args).call
end
# Service initializer
def initialize(args={})
unless args.is_a?(Hash)
raise ArgumentError, "provided 'args' should be a hash."
end
args.each { |k,v| send("#{k.to_s}=", v) }
end
end
end
end
@bobmaerten
Copy link

bobmaerten commented Feb 1, 2022

Ce ne serait pas un double splat qu'il convierait d'utiliser ligne 22-23 ?

   def self.call(**args)
     new(**args).call
   end

@ccyrille
Copy link
Author

ccyrille commented Feb 1, 2022

@bobmaerten l'avantage de "laisser passer" ce qui n'est pas un hash au niveau du call pour s'en protéger par la suite (ArgumentError au niveau de initialize) est qu'on renvoie une exception nettement plus explicite si autre chose qu'un hash est passé ;-)

class SayHello
  include Service
	
  attr_accessor :name
	
  def call
    puts "hello #{name}"
  end
end 

Version avec double splat :

$> SayHello.call("bob")
...
(irb):5:in `call': wrong number of arguments (given 1, expected 0) (ArgumentError)

Version proposée :

$> SayHello.call("bob")
...
(irb):12:in `initialize': provided 'args' should be a hash. (ArgumentError)

@bobmaerten
Copy link

Hon! Clever :)
Merci pour le détail du pourquoi.

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