Class: Dio::Forwarders::AttributeForwarder

Inherits:
BaseForwarder
  • Object
show all
Defined in:
lib/dio/forwarders/attribute_forwarder.rb

Overview

A more controlled forwarder that targets only ‘attr_` type methods like `attr_reader` and `attr_accessor`. These attributes are found by diffing instance variables and method names to find generated accessor methods.

It should be noted that this could be faster if there was an assumption of purity at the time of the match. I may make another variant for that.

Author:

  • baweaver

Since:

  • 0.0.3

Constant Summary collapse

NEW_DIVE =

Wrapper for creating a new Forwarder

Since:

  • 0.0.3

-> v { new(v) }

Instance Method Summary collapse

Constructor Details

#initialize(base_object) ⇒ AttributeForwarder

Returns a new instance of AttributeForwarder.

Since:

  • 0.0.3



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/dio/forwarders/attribute_forwarder.rb', line 19

def initialize(base_object)
  ivars = Set.new base_object
    .instance_variables
    .map { _1.to_s.delete('@').to_sym }

  all_methods = Set.new base_object.methods

  @attributes = ivars.intersection(all_methods)

  super
end

Instance Method Details

#deconstructArray

Deconstructs from a list of attribute names, wrapping each value in a new dive in case the pattern match goes further than one level.

Returns:

  • (Array)

Since:

  • 0.0.3



35
36
37
38
39
# File 'lib/dio/forwarders/attribute_forwarder.rb', line 35

def deconstruct
  return @base_object.map(&NEW_DIVE) if @base_object.is_a?(Array)

  @attributes.map { NEW_DIVE[@base_object.public_send(_1)] }
end

#deconstruct_keys(keys) ⇒ Hash

Deconstructs attributes from an object, wrapping each value in a new dive in case the pattern match goes further than one level.

Parameters:

  • keys (Array)

    Keys to be extracted, diffed against possible attributes

Returns:

  • (Hash)

Since:

  • 0.0.3



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/dio/forwarders/attribute_forwarder.rb', line 52

def deconstruct_keys(keys)
  key_set      = Set.new(keys)
  unknown_keys = key_set - @attributes

  if unknown_keys.any?
    raise Dio::Errors::UnknownAttributesProvided.new(unknown_keys)
  end

  known_keys = @attributes.intersection(key_set)

  known_keys.to_h { [_1, NEW_DIVE[@base_object.public_send(_1)]] }
end

#valueAny Also known as: __getobj__

Unwrapped context, aliased afterwards to use Ruby’s delegator interface

Returns:

  • (Any)

    Originally wrapped object

Since:

  • 0.0.3



69
70
71
# File 'lib/dio/forwarders/attribute_forwarder.rb', line 69

def value
  @base_object
end