module WrapIt::Arguments::ClassMethods
{Arguments} Class methods to include
Attributes
Public Instance Methods
Desclares argument for capturing on initialization process.
Inside initialization process, all arguments (except options hash), passed to constructor will be inspected to satisfy conditions, specified in `:if` and `:and` options. If this happens, and block given, it evaluated in context of component instance. If no block given, setter with `name` will be attempted to set value. In any way if conditions satisfied, argument removed from future processing.
If no conditions specified, the `name` of attribute taked as only condition.
@example without conditions - name is a condition
class Button < WrapIt::Base argument(:disabled) { |name, value| puts 'DISABLED' } end Button.new(template, :disabled) # => 'DISABLED' Button.new(template, 'disabled') # => nothing
@example with conditions and setter
class Button < WrapIt::Base argument :disabled, if: /^disable(?:d)?$/ def disabled=(value) puts 'DISABLED' end end Button.new(template, :disabled) # => 'DISABLED' Button.new(template, 'disabled') # => 'DISABLED' Button.new(template, :disable) # => 'DISABLED' Button.new(template, 'some_text') # => nothing
@overload argument(name, opts = {}, &block)
@param name [Symbol] unique name, used to refer to this declaration @param opts [Hash] options @option opts [Object] :if one or array of conditions that should be satisfied to capture argument. See {CaptureArray} for details. If array given, conditions will be or'ed. @option opts [Object] :and additional one or array of conditions, that will be and'ed with :if conditions. @option opts [Boolean] :first_only (false) stop processing on first match @option opts [Boolean] :after_options (false) process this argument after options @yield [name, value] yields every time argument captured. Evaluated in instance context @yieldparam name [Symbol] name of argument, specified in name param above @yieldparam value [Object] real argument value
@return [void] @since 1.0.0
# File lib/wrap_it/arguments.rb, line 94 def argument(name, first_only: false, after_options: false, **opts, &block) name.is_a?(String) && name = name.to_sym fail ArgumentError, 'Wrong name' unless name.is_a?(Symbol) arguments[name] = { name: name, conditions: Arguments.make_conditions(name, **opts), block: block, first_only: first_only == true, after_options: after_options == true } end
Capture arguments for class and it's ancestors. All captured arguments and options will be extracted from original `args` argument.
Actually you rare needs to call this method directly. For example you can call it in instance {Arguments#capture_arguments! capture_arguments!} override to capture arguments for some child components.
@example capturing arguments for child component
class Button < WrapIt::Base option(:color) { |name, value| puts "BUTTON COLOR IS: #{value}" } end class Toolbar < WrapIt::Base protected def capture_arguments!(args, &block) @button = Button.new(Button.capture_arguments!(args)) super(args, &block) # ! don't forget to call parent method end end Toolbar.new(template, color: :red) # => 'BUTTON COLOR IS red'
@overload capture_arguments!(args, opts = {}, &block)
@param args [Array<Object>] arguments to process (include options) @param opts [Hash] options @option opts [Boolean] :inherited (true) process ancestors @option opts [Base] :instance (nil) if specified valid instance, all {ClassMethods#argument} and {ClassMethods#option} blocks will and setters will be called. @param &block [Proc] block, passed to constructor if present
@return [Array<Object>] captured arguments
# File lib/wrap_it/arguments.rb, line 200 def capture_arguments!(args, inherited = true, instance = nil, &block) opts = args.extract_options! if inherited arg_parents.select { |a| a.protected_methods.include?(:extract_for_class) } .each { |a| a.extract_for_class(args, opts, instance, &block) } result_args = collect_derived(:@provided_arguments, {}, :merge) .values .flatten result_opts = collect_derived(:@provided_options, {}, :merge) .values .reduce({}) { |a, e| a.merge!(e) } else extract_for_class(args, opts, instance, &block) result_args = @provided_arguments.values.flatten result_opts = @provided_options .values .reduce({}) { |a, e| a.merge!(e) } end opts.empty? || args << opts result_opts.empty? || result_args << result_opts result_args end
Desclares option for capturing on initialization process.
Provides same manner as {#argument} but for hash of options, passed to constructor. Specified conditions are applied to options keys, not to values.
> Hint: you can specify argument and options with same name to call > same setter.
@example shared setter
class Button < WrapIt::Base REGEXP = /^disable(?:d)?$/ argument :disabled, if: REGEXP option :disabled, if: %i(disable disabled) def disabled=(value) if value == true || REGEXP =~ value.to_s puts 'DISABLED' end end end Button.new(template, :disabled) # => 'DISABLED' Button.new(template, 'disabled') # => 'DISABLED' Button.new(template, :disable) # => 'DISABLED' Button.new(template, disabled: true) # => 'DISABLED' Button.new(template, disable: true) # => 'DISABLED' Button.new(template, disable: false) # => nothing Button.new(template, 'some_text') # => nothing
@overload option(name, opts = {}, &block)
@param name [Symbol] unique name, used to refer to this declaration @param opts [Hash] options @option opts [Object] :if see {WrapIt::Arguments::ClassMethods#argument} @option opts [Object] :and see {WrapIt::Arguments::ClassMethods#argument} @yield [name, value] yields every time option captured. Evaluated in instance context @yieldparam name [Symbol] name of option, specified in name param above @yieldparam value [Object] real option value
@return [void] @since 1.0.0
# File lib/wrap_it/arguments.rb, line 154 def option(name, after: nil, **opts, &block) name.is_a?(String) && name = name.to_sym fail ArgumentError, 'Wrong name' unless name.is_a?(Symbol) @dependencies = !after.nil? options[name] = { name: name, conditions: Arguments.make_conditions(name, **opts), block: block } end
Protected Instance Methods
# File lib/wrap_it/arguments.rb, line 225 def arg_parents @arg_parents ||= ancestors.take_while { |a| a != Arguments.base } .reverse .unshift(Arguments.base) end
# File lib/wrap_it/arguments.rb, line 244 def argument_provided?(*list) return false if provided_arguments.nil? if list.empty? return provided_arguments.empty? else return list.all? do |arg| provided_arguments.key?(arg) end end end
# File lib/wrap_it/arguments.rb, line 263 def arguments @arguments ||= {} end
# File lib/wrap_it/arguments.rb, line 255 def block_provided? provided_block.is_a?(Proc) end
# File lib/wrap_it/arguments.rb, line 267 def extract_args(args, list, instance = nil) args.respond_to?(:extract!) || args.extend(WrapIt::CaptureArray) list.each do |arg| processed = if arg[:first_only] [args.capture_first!(*arg[:conditions])].compact else args.capture!(*arg[:conditions]) end (provided_arguments[arg[:name]] ||= []).concat(processed) next if instance.nil? processed.each do |v| instance.instance_exec(arg[:name], v, arg[:block], &SETTER) end end end
# File lib/wrap_it/arguments.rb, line 300 def extract_for_class(args, opts, instance = nil, &block) @provided_options = {} @provided_arguments = {} @provided_block = block after, before = arguments.values.partition { |x| x[:after_options] } extract_args(args, before, instance) extract_opts(opts, instance) extract_args(args, after, instance) @provided_block = nil end
# File lib/wrap_it/arguments.rb, line 284 def extract_opts(opts, instance = nil) keys = opts.keys.extend(WrapIt::CaptureArray) options.each do |name, opt| (provided_options[name] ||= {}).merge!(Hash[ keys.capture!(*opt[:conditions]) .map do |key| value = opts.delete(key) unless instance.nil? instance.instance_exec(key, value, opt[:block], &SETTER) end [key, value] end ]) end end
# File lib/wrap_it/arguments.rb, line 233 def option_provided?(*list) return false if provided_options.nil? if list.empty? return provided_options.empty? else return list.all? do |option| provided_options.key?(option) end end end
# File lib/wrap_it/arguments.rb, line 259 def options @options ||= {} end