module NamedParameters
Include this module to enable the NamedParameters#named_parameters
macros
Public Instance Methods
Works like NamedParameters#named_parameters
, but instead of using it right before a method definition, you use it afterwards. You can also add the strict and super mode. Replace the my_method
with the name of the method that you want to have named parameters @see NamedParameters#named_parameters
@see NamedParameters#named_parameters_strict
@see NamedParameters#named_parameters_super
@see NamedParameters#named_parameters_strict_super
# File lib/named_parameters.rb 13 def my_method_has_named_parameters(optionals = { }) 14 # Empty method just for the documentation. Those methods are realized in NamedParameters#method_missing 15 end
Makes the next method callable via named parameters (options hash) The caller hash may contain keys that are not contained in the parameters of the next method @param [Hash] optionals Optional default values for the parameters
# File lib/named_parameters.rb 20 def named_parameters(optionals = { }) 21 _named_parameters optionals, false, false 22 end
Makes the next method callable via named parameters (options hash) The caller hash may only contain keys that are in the parameters of the next method @param [Hash] optionals Optional default values for the parameters
# File lib/named_parameters.rb 27 def named_parameters_strict(optionals = { }) 28 _named_parameters optionals, true, false 29 end
Makes the next method callable via named parameters (options hash) and calls super with this options hash as the only parameter The caller hash may only contain keys that are in the parameters of the next method @param [Hash] optionals Optional default values for the parameters
# File lib/named_parameters.rb 43 def named_parameters_strict_super(optionals = { }) 44 _named_parameters optionals, true, true 45 end
Makes the next method callable via named parameters (options hash) and calls super with this options hash as the only parameter The caller hash may contain keys that are not contained in the parameters of the next method @param [Hash] optionals Optional default values for the parameters
# File lib/named_parameters.rb 35 def named_parameters_super(optionals = { }) 36 _named_parameters optionals, false, true 37 end
Private Instance Methods
Checks whether there are keys in the options, that are not in the parameter_names. Throws a user friendly RuntimeError in that case
# File lib/named_parameters.rb 150 def _check_for_not_needed_options(options, parameter_names, method_name) 151 options.each do |name, _| 152 raise ("Parameter '#{name}' is not accepted by '#{method_name}'") unless parameter_names.member? name 153 end 154 end
@param [Hash] optionals Optional default values for the parameters @param [Boolean] strict Shall keys in the caller options hash, that are not in the parameter list, throw an error? @param [Boolean] call_super Shall super be called with the caller option hash as the only parameter?
# File lib/named_parameters.rb 99 def _named_parameters(optionals, strict, call_super) 100 # remember the preferences for the next method, that is added 101 @named_parameters_optionals = optionals 102 @named_parameters_strict = strict 103 @named_parameters_super = call_super 104 # make sure only one method is redefined after the named_parameters macro was called 105 @redefine_next = true 106 end
Builds the actual parameter array for the redirected call to the original method
# File lib/named_parameters.rb 139 def _parameters_from_options(options, optionals, parameter_names, method_name) 140 parameters ||= [] 141 parameter_names.each do |name| 142 parameters << options.fetch(name) { optionals.fetch(name) { raise "Mandatory parameter #{name} is not passed to 143 method #{method_name}" } } 144 end 145 parameters 146 end
Redefines a method so the caller can use named parameters instead of ordinary parameters @param [Symbol] method_name @param [Hash] optionals Optional default values for the parameters @param [Boolean] strict Shall keys in the caller options hash, that are not in the parameter list, throw an error? @param [Boolean] call_super Shall super be called with the caller option hash as the only parameter?
# File lib/named_parameters.rb 113 def _redefine_with_named_parameters(method_name, optionals, strict, call_super) 114 # the method as defined in the class/module 115 original_method ||= instance_method method_name 116 # names of the parameters as defined in the class/module 117 parameter_names ||= original_method.parameters.collect { |_, b| b } 118 new_name_for_original_method ||= (method_name.to_s + '_before_named_parameters').to_sym 119 120 # "safe" original method 121 alias_method new_name_for_original_method, method_name 122 123 # redefine old method with new logic redirecting to original method 124 define_method method_name do |options = { }, &block| 125 # check parameters if strict 126 _check_for_not_needed_options options, parameter_names, method_name if strict 127 # call super if so wanted 128 super(options) if call_super 129 130 # build parameter array from options and optionals 131 parameters ||= _parameters_from_options options, optionals, parameter_names, method_name 132 133 # redirect to original method 134 send new_name_for_original_method, *parameters, &block 135 end 136 end
Makes sure a method is redefined as soon as it is defined. Only when named_parameters
was called right before
# File lib/named_parameters.rb 83 def method_added(method_name) 84 # redefine the method 85 if @redefine_next 86 @redefine_next = false 87 _redefine_with_named_parameters(method_name, 88 @named_parameters_optionals, 89 @named_parameters_strict, 90 @named_parameters_super) 91 end 92 # call old method_added 93 method_added_before_named_parameters method_name 94 end
Enables the <method>_has_named_parameter ghost methods
# File lib/named_parameters.rb 63 def method_missing method, *args, &block 64 # catch only methods like <method_name> + _has_named_parameters + <mode definition> 65 if /\A(?<method_name>.+)_has_named_parameters(?<mode>_super_strict|_strict_super|_super|_strict)?\z/ =~ method.to_s 66 # find out mode 67 mode = "" if mode.nil? 68 call_super = mode.include? 'super' 69 # find out strict 70 strict = mode.include? 'strict' 71 # redefine 72 _redefine_with_named_parameters(method_name, 73 args[0] || { }, 74 strict, 75 call_super) 76 else 77 # if method is not like above pattern, do the original stuff 78 super method, *args, &block 79 end 80 end