class BetterStruct

Constants

BEFORE_FIRST_DIGIT_OR_NON_UNDERSCORED_REGEXP
CAMELCASE_ABBREVIATION_REGEX
CAMELCASE_REGEX
EMPTY_STRING
EQUAL_SIGN
MAP_METHOD_NAMES
NON_ENGLISH_REGEXP
NON_UNDERSCORED_BEGIN_OR_END_REGEXP
TRANSLITERATION_FROM
TRANSLITERATION_TO
UNDERSCORE_DUPLICATES_REGEXP
UNDERSCORE_MASK
UNDERSCORE_SIGN
VERSION

Attributes

value[R]

Public Class Methods

new(value = nil) click to toggle source
# File lib/better_struct.rb, line 11
def initialize(value = nil)
  @value = value
  __load_defined_methods
end

Public Instance Methods

==(other) click to toggle source
# File lib/better_struct.rb, line 16
def ==(other)
  other.is_a?(self.class) && value == other.value
end
empty?() click to toggle source
# File lib/better_struct.rb, line 28
def empty?
  value.respond_to?(:empty?) ? value.empty? : !value
end
inspect() click to toggle source
# File lib/better_struct.rb, line 20
def inspect
  "#{ self.class }<#{ value.inspect }>"
end
to_s() click to toggle source
# File lib/better_struct.rb, line 24
def to_s
  value.to_s
end

Private Instance Methods

__assignment?(method_name) click to toggle source
# File lib/better_struct.rb, line 54
def __assignment?(method_name)
  method_name[-1] == EQUAL_SIGN
end
__delegate_method(method_name, *args, &block) click to toggle source
# File lib/better_struct.rb, line 58
def __delegate_method(method_name, *args, &block)
  result = value.public_send(method_name, *__unwrap_items(args), &__wrap_block_args(&block))
  result = __unwrap_items(result) if MAP_METHOD_NAMES.include?(method_name)

  __wrap(result)
end
__load_defined_methods() click to toggle source
# File lib/better_struct.rb, line 34
def __load_defined_methods
  @__defined_methods = {}

  if value && value.respond_to?(:each_pair)
    value.each_pair { |k, v| @__defined_methods[__methodize(k)] = v }
  end
end
__methodize(value) click to toggle source
# File lib/better_struct/methodize.rb, line 19
def __methodize(value)
  string = value.to_s
  return string if __methodized?(string)

  duplicated_string = string.dup

  __transliterate!(duplicated_string)
  __underscore!(duplicated_string)

  duplicated_string
end
__methodized?(string) click to toggle source
# File lib/better_struct/methodize.rb, line 31
def __methodized?(string)
  return false if string =~ BEFORE_FIRST_DIGIT_OR_NON_UNDERSCORED_REGEXP
  return false if string =~ UNDERSCORE_DUPLICATES_REGEXP
  true
end
__transliterate!(string) click to toggle source
# File lib/better_struct/methodize.rb, line 37
def __transliterate!(string)
  if string =~ NON_ENGLISH_REGEXP
    string.tr!(TRANSLITERATION_FROM, TRANSLITERATION_TO)
  end
end
__underscore!(string) click to toggle source
# File lib/better_struct/methodize.rb, line 43
def __underscore!(string)
  string.gsub!(CAMELCASE_ABBREVIATION_REGEX, UNDERSCORE_MASK)
  string.gsub!(CAMELCASE_REGEX, UNDERSCORE_MASK)
  string.downcase!
  string.gsub!(NON_UNDERSCORED_BEGIN_OR_END_REGEXP, EMPTY_STRING)
  string.gsub!(BEFORE_FIRST_DIGIT_OR_NON_UNDERSCORED_REGEXP, UNDERSCORE_SIGN)
  string.gsub!(UNDERSCORE_DUPLICATES_REGEXP, UNDERSCORE_SIGN)
end
__unwrap(value) click to toggle source
# File lib/better_struct.rb, line 82
def __unwrap(value)
  value.is_a?(self.class) ? value.value : value
end
__unwrap_items(items) click to toggle source
# File lib/better_struct.rb, line 78
def __unwrap_items(items)
  items.is_a?(Array) ? items.map! { |i| __unwrap(i) } : items
end
__wrap(value) click to toggle source
# File lib/better_struct.rb, line 65
def __wrap(value)
  value.is_a?(self.class) ? self : self.class.new(value)
end
__wrap_block_args() { |*wrapped_arguments| ... } click to toggle source
# File lib/better_struct.rb, line 69
def __wrap_block_args
  return unless block_given?

  Proc.new do |*args|
    wrapped_arguments = args.map! { |arg| __wrap(arg) }
    yield(*wrapped_arguments)
  end
end
method_missing(method_name, *args, &block) click to toggle source
# File lib/better_struct.rb, line 42
def method_missing(method_name, *args, &block)
  method_name = method_name.to_s

  if value.respond_to?(method_name)
    __delegate_method(method_name, *args, &block)
  elsif __assignment?(method_name)
    @__defined_methods[method_name[0...-1]] = args.first
  else
    __wrap(@__defined_methods[method_name])
  end
end