module EnsureIt
@private
Constants
- BIN_REGEXP
- ENSURES
- FLOAT_REGEXP
- HEX_REGEXP
- INT_REGEXP
- OCT_REGEXP
- OPERATIONS
- TRUE_NAMES
- VERSION
Public Class Methods
config()
click to toggle source
# File lib/ensure_it/config.rb, line 24 def self.config Config end
configure() { |Config| ... }
click to toggle source
# File lib/ensure_it/config.rb, line 28 def self.configure yield(Config) if block_given? Config end
ensure_array(arr, *args, values: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_array.rb, line 46 def self.ensure_array(arr, *args, values: nil, **opts) args.each do |arg| if arg.is_a?(Proc) arr = arr.map(arg) next end arg = arg.ensure_symbol || next case arg when *ENSURES arr = case arg when :ensure_symbol then arr.map { |x| x.ensure_symbol } when :ensure_symbol! then arr.map { |x| x.ensure_symbol! } when :ensure_string then arr.map { |x| x.ensure_string } when :ensure_string! then arr.map { |x| x.ensure_string! } when :ensure_integer then arr.map { |x| x.ensure_integer } when :ensure_integer! then arr.map { |x| x.ensure_integer! } when :ensure_float then arr.map { |x| x.ensure_float } when :ensure_float! then arr.map { |x| x.ensure_float! } when :ensure_array then arr.map { |x| x.ensure_array } when :ensure_array! then arr.map { |x| x.ensure_array! } when :ensure_class then arr.map { |x| x.ensure_class } when :ensure_class! then arr.map { |x| x.ensure_class! } end when *OPERATIONS op = arg == :sort_desc ? :sort : arg arr = arr.send(op) arr = arr.reverse if arg == :sort_desc else arr = arr.map { |x| x.respond_to?(arg) ? x.send(arg) : nil } end end values.is_a?(Array) ? arr & values : arr end
ensure_array_error(**opts)
click to toggle source
# File lib/ensure_it/ensure_array.rb, line 102 def self.ensure_array_error(**opts) opts[:message] ||= '#{subject} should be an Array' opts end
ensure_boolean_error(**opts)
click to toggle source
# File lib/ensure_it/ensure_boolean.rb, line 68 def self.ensure_boolean_error(**opts) unless opts.key?(:message) opts[:message] = '#{subject} should be a boolean or be able' \ ' to convert to it' end opts end
ensure_class(klass, *args, values: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_class.rb, line 67 def self.ensure_class(klass, *args, values: nil, **opts) args.select! { |x| x.is_a?(Module) } throw :wrong unless args.all? { |x| klass <= x } throw :wrong if values.is_a?(Array) && !values.include?(klass) klass end
ensure_class_string(str, *args, **opts)
click to toggle source
# File lib/ensure_it/ensure_class.rb, line 57 def self.ensure_class_string(str, *args, **opts) opts.delete(:name_of) opts.delete(:exist) name = EnsureIt::StringUtils.ensure_name( str, name_of: :class, exist: true, **opts ) throw :wrong if name.nil? EnsureIt.ensure_class(Object.const_get(name), *args, **opts) end
ensure_float(float, values: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_float.rb, line 76 def self.ensure_float(float, values: nil, **opts) throw :wrong if values.is_a?(Array) && !values.include?(float) float end
ensure_float_error(**opts)
click to toggle source
# File lib/ensure_it/ensure_float.rb, line 81 def self.ensure_float_error(**opts) unless opts.key?(:message) opts[:message] = '#{subject} should be a float or be able' \ ' to convert to it' end opts end
ensure_integer(int, values: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_integer.rb, line 116 def self.ensure_integer(int, values: nil, **opts) throw :wrong if values.is_a?(Array) && !values.include?(int) int end
ensure_integer_error(**opts)
click to toggle source
# File lib/ensure_it/ensure_integer.rb, line 133 def self.ensure_integer_error(**opts) unless opts.key?(:message) opts[:message] = '#{subject} should be an integer or be able' \ ' to convert to it' end opts end
ensure_integer_string(str, **opts)
click to toggle source
# File lib/ensure_it/ensure_integer.rb, line 121 def self.ensure_integer_string(str, **opts) value = case str when OCT_REGEXP then opts[:octal] == true ? str.to_i(8) : str.to_i when INT_REGEXP then str.to_i when HEX_REGEXP then str[2..-1].to_i(16) when BIN_REGEXP then str[2..-1].to_i(2) else throw :wrong end return value if opts.empty? return EnsureIt.ensure_integer(value, **opts) end
ensure_string(str, values: nil, downcase: nil, name_of: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_string.rb, line 129 def self.ensure_string(str, values: nil, downcase: nil, name_of: nil, **opts) if name_of.nil? value = downcase == true ? str.downcase : str else value = EnsureIt::StringUtils.ensure_name( str, downcase: downcase, name_of: name_of, **opts ) throw :wrong if value.nil? end throw :wrong if values.is_a?(Array) && !values.include?(value) value end
ensure_string_error(**opts)
click to toggle source
# File lib/ensure_it/ensure_string.rb, line 142 def self.ensure_string_error(**opts) unless opts.key?(:message) opts[:message] = '#{subject} should be a String or a Symbol' if opts[:numbers] == true opts[:message] << ' or a Numeric' end if opts.key?(:name_of) opts[:message] << " and should be a name of #{opts[:name_of]}" end if opts[:values].is_a?(Array) opts[:message] << " and should contained in #{opts[:values]}" end end opts end
ensure_symbol(sym, values: nil, downcase: nil, name_of: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_symbol.rb, line 51 def self.ensure_symbol(sym, values: nil, downcase: nil, name_of: nil, **opts) if name_of.nil? value = downcase == true ? sym.to_s.downcase.to_sym : sym else value = EnsureIt::StringUtils.ensure_name( sym.to_s, downcase: downcase, name_of: name_of, **opts ) throw :wrong if value.nil? value = value.to_sym end throw :wrong if values.is_a?(Array) && !values.include?(value) value end
ensure_symbol_error(**opts)
click to toggle source
# File lib/ensure_it/ensure_symbol.rb, line 65 def self.ensure_symbol_error(**opts) unless opts.key?(:message) opts[:message] = '#{subject} should be a Symbol or a String' if opts.key?(:name_of) opts[:message] << " and should be a name of #{opts[:name_of]}" end if opts[:values].is_a?(Array) opts[:message] << " and should contained in #{opts[:values]}" end end opts end
raise_error(method_name, message: nil, error: nil, **opts)
click to toggle source
# File lib/ensure_it/errors.rb, line 62 def self.raise_error(method_name, message: nil, error: nil, **opts) error = EnsureIt.config.error_class if error.nil? || !(error <= Exception) error_msg = ErrorMessage.new(method_name, message, caller[1..-1]) # save message in backtrace in variables to not call getter # methods of error_msg instance in raise call error_message = error_msg.message error_backtrace = error_msg.backtrace if opts[:smart] == true || EnsureIt.config.errors == :smart inspect_source(error_msg, **opts) activate_smart_errors(error_msg, **opts) end raise error, error_message, error_backtrace end
refined?()
click to toggle source
# File lib/ensure_it.rb, line 14 def self.refined? ENSURE_IT_REFINED == true end
Private Class Methods
activate_smart_errors(error, **opts)
click to toggle source
# File lib/ensure_it/errors.rb, line 76 def self.activate_smart_errors(error, **opts) tp_count = 0 error_obj = nil # # first trace point is to capture raise object before exitting # from :ensure_* method # # after that with second trace point we try to return from :ensure_* method # to caller and inspect code there for method name and arguments TracePoint.trace(:return, :raise) do |first_tp| if first_tp.event == :raise # save error object for patching error_obj = first_tp.raised_exception else # skip returns from :raise_smart_error and :raise_error tp_count += 1 if tp_count > 2 first_tp.disable # at this moment we are at the end of 'ensure_' method # skip last code line in :ensure_* method TracePoint.trace(:return, :line) do |second_tp| # now we are in caller context second_tp.disable unless error_obj.nil? # inspect caller code inspect_code(second_tp, error, **opts) # patch error message msg = error.message error_obj.define_singleton_method(:message) { msg } end end end end end end
inspect_code(tp, error, **opts)
click to toggle source
# File lib/ensure_it/errors.rb, line 140 def self.inspect_code(tp, error, **opts) return if tp.method_id.nil? error.inside = tp.method_id begin method = eval("method(:#{tp.method_id})", tp.binding) rescue NameError return end param = method.parameters.find { |_, name| name.to_s == error.subject } unless param.nil? error.subject_type = "#{param[0]}_argument".to_sym end end
inspect_source(error, **opts)
click to toggle source
# File lib/ensure_it/errors.rb, line 112 def self.inspect_source(error, **opts) file_name, line_no = error.backtrace.first.split(':', 2) return unless File.exist?(file_name) line_no = line_no.to_i line = read_line_number(file_name, line_no) return if line.nil? m_name = error.method_name m = / (?:(?<method_access>\.)|(?<class_access>@{1,2}))? (?<name>(?:[a-z_][a-zA-Z_0-9]*(?<modifier>[?!])?)|\)) (?: (?<send>\.send\(\s*(?::#{m_name}|'#{m_name}'|"#{m_name}")\s*\))| (?:\.#{m_name}(?:[^a-zA-Z_0-9]|\z)) ) /x.match(line) return if m.nil? || m[:method_access].nil? && !m[:modifier].nil? error.subject = m[:name] error.subject_type = case when m[:class_access] then m[:class_access] == '@' ? :instance_variable : :class_variable when m[:name] == ')' then error.subject = nil :unknown_method_result when m[:method_access] then :method_result else :local_variable end end
patch(target, &block)
click to toggle source
# File lib/ensure_it/patch.rb, line 3 def self.patch(target, &block) module_eval do refine target do class_eval(&block) end end end
read_line_number(file_name, number)
click to toggle source
# File lib/ensure_it/errors.rb, line 154 def self.read_line_number(file_name, number) counter, line = 0, nil File.foreach(file_name) do |l| counter += 1 if counter == number line = l.chomp! break end end line end
Public Instance Methods
ensure_array(*args, default: [], make: false, **opts)
click to toggle source
# File lib/ensure_it/ensure_array.rb, line 4 def ensure_array(*args, default: [], make: false, **opts) return default if make != true EnsureIt.ensure_array([self], *args, **opts) end
ensure_array!(*args, make: false, **opts)
click to toggle source
# File lib/ensure_it/ensure_array.rb, line 9 def ensure_array!(*args, make: false, **opts) return EnsureIt.ensure_array([self], *args, **opts) if make == true EnsureIt.raise_error(:ensure_array!, **EnsureIt.ensure_array_error(**opts)) end
ensure_boolean(default: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_boolean.rb, line 5 def ensure_boolean(default: nil, **opts) default end
ensure_boolean!(**opts)
click to toggle source
# File lib/ensure_it/ensure_boolean.rb, line 9 def ensure_boolean!(**opts) EnsureIt.raise_error(:ensure_boolean!, **EnsureIt::ensure_boolean_error(**opts)) end
ensure_class(*args, default: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_class.rb, line 3 def ensure_class(*args, default: nil, **opts) default end
ensure_class!(*args, **opts)
click to toggle source
# File lib/ensure_it/ensure_class.rb, line 7 def ensure_class!(*args, **opts) opts[:message] ||= '#{subject} should be a class' EnsureIt.raise_error(:ensure_class!, **opts) end
ensure_float(default: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_float.rb, line 5 def ensure_float(default: nil, **opts) default end
ensure_float!(**opts)
click to toggle source
# File lib/ensure_it/ensure_float.rb, line 9 def ensure_float!(**opts) EnsureIt.raise_error(:ensure_float!, **EnsureIt::ensure_float_error(**opts)) end
ensure_hash(*args, default: {}, **opts)
click to toggle source
# File lib/ensure_it/ensure_hash.rb, line 3 def ensure_hash(*args, default: {}, **opts) default end
ensure_hash!(*args, **opts)
click to toggle source
# File lib/ensure_it/ensure_hash.rb, line 7 def ensure_hash!(*args, **opts) opts[:message] ||= '#{subject} should be a Hash' EnsureIt.raise_error(:ensure_hash!, **opts) end
ensure_instance_of(klass, default: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_instance_of.rb, line 3 def ensure_instance_of(klass, default: nil, **opts) unless klass.is_a?(Class) fail( ArgumentError, 'Wrong class argument for #ensure_instance_of specified' ) end is_a?(klass) ? self : default end
ensure_instance_of!(klass, **opts)
click to toggle source
# File lib/ensure_it/ensure_instance_of.rb, line 13 def ensure_instance_of!(klass, **opts) unless klass.is_a?(Class) fail( ArgumentError, 'Wrong class argument for #ensure_instance_of specified' ) end return self if is_a?(klass) opts[:message] ||= "\#{subject} should be an instance of '#{klass.name}' class" EnsureIt.raise_error(:ensure_instance_of!, **opts) end
ensure_integer(default: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_integer.rb, line 3 def ensure_integer(default: nil, **opts) default end
ensure_integer!(**opts)
click to toggle source
# File lib/ensure_it/ensure_integer.rb, line 7 def ensure_integer!(**opts) EnsureIt.raise_error(:ensure_integer!, **EnsureIt::ensure_integer_error(**opts)) end
ensure_string(default: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_string.rb, line 57 def ensure_string(default: nil, **opts) default end
ensure_string!(**opts)
click to toggle source
# File lib/ensure_it/ensure_string.rb, line 61 def ensure_string!(**opts) EnsureIt.raise_error(:ensure_string!, **EnsureIt.ensure_string_error(**opts)) end
ensure_symbol(default: nil, **opts)
click to toggle source
# File lib/ensure_it/ensure_symbol.rb, line 3 def ensure_symbol(default: nil, **opts) default end
ensure_symbol!(**opts)
click to toggle source
# File lib/ensure_it/ensure_symbol.rb, line 7 def ensure_symbol!(**opts) EnsureIt.raise_error(:ensure_symbol!, **EnsureIt.ensure_symbol_error(**opts)) end