Module: Bruv

Defined in:
lib/bruv.rb,
lib/bruv/version.rb

Overview

Module adding Bruv.attribute and Bruv.attributes helper methods. It adds an initializer method which sets values for defined attributes and perform additional conversions if specified.

Examples:

class MyClass
  include Bruv
  attribute :price, ->(ci) { Float(ci) }
  attributes :age, :type
end

mc = MyClass.new("123", 100, :user)
mc.first_name # => 123.00
mc.age        # => 100
mc.type       # => :user

Defined Under Namespace

Classes: BruvArgumentError

Constant Summary collapse

VERSION =
"0.2.2"

Class Method Summary collapse

Class Method Details

.included(obj) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/bruv.rb', line 22

def self.included(obj)
  obj.class_eval do
    # Array of registered attribute names.
    @instance_variables = []

    # Hash of procs for registered attributes.
    @procs = {}

    # Getter for @instance_variables
    # @return [Array]
    def self.instance_variables
      @instance_variables
    end

    # Getter for @procs
    # @return [Hash]
    def self.procs
      @procs
    end

    # Appends single variable name to {instance_variables} and if mproc
    # is passed it adds it to {procs}.
    # @param name [#to_sym] Name of the variable to be defined.
    # @param mproc [#call] Proc called in the #initialize method
    #   which can perform additional value conversions
    # @return [Hash]
    # @example
    #   attribute :tag, ->(t) { t.downcase }
    #   attribute :code, ->(c) { { a: 123, b: 321 }.fetch(c) }
    def self.attribute(name, mproc = nil)
      mname = name.to_sym
      instance_variables << mname
      procs[mname] = mproc
    end

    # Appends multiple variable names to {instance_variables}
    # @param *names [Array<#to_sym>] Array of names, each name variable should
    #   respond to #to_sym
    # @return [Array]
    # @example
    #   attributes :first_name, :last_name
    def self.attributes(*names)
      @instance_variables += names.map(&:to_sym)
    end

    # Defines getter methods for each attribute in {instance_variables},
    # and calls a proc for an attribute if it was registered.
    # @note Attributes are defined in order in which they were registered.
    # @param *args [Array] Array of attribute values.
    # @raise [BruvArgumentError] when more values are passed that registered attributes.
    def initialize(*args)
      raise_argument_error if args.size > self.class.instance_variables.size
      self.class.instance_variables.each_with_index do |var, index|
        mproc = self.class.procs[var.to_sym] || proc { |a| a }
        instance_variable_set("@#{var}", mproc.call(args[index]))
        define_singleton_method(var) { instance_variable_get("@#{var}") }
      end
    end

    private

    # Prepares Error message
    def raise_argument_error
      message = "Number of arguments exceeds number of instance variables for:"
      raise BruvArgumentError, "#{message} #{self.class.name}"
    end
  end
end