Class: ChainableResult

Inherits:
Object
  • Object
show all
Defined in:
lib/chainable_result.rb

Direct Known Subclasses

Array, Future, Hash, Other

Defined Under Namespace

Classes: Array, Future, Hash, Other

Constant Summary collapse

WITH_RESOLVED =

Shorter names are deprecated

WITH = method(:with)
SYNC_WITH_RESOLVED =
SYNC_WITH = method(:sync_with)
RESOLVE_ITEM =
method(:resolve_item)
CACHE_MODE_KEY =
:"ChainableResult::USE_CACHE"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, method = nil, args = [], opts = {}, &block) ⇒ ChainableResult

Returns a new instance of ChainableResult.



2
3
4
5
6
7
8
9
# File 'lib/chainable_result.rb', line 2

def initialize(source, method = nil, args = [], opts = {}, &block)
  @source = source
  @method = method || (block ? :then : :itself)
  @args = args
  @opts = opts
  @block = block
  @cached = false
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, **opts, &block) ⇒ Object



47
48
49
# File 'lib/chainable_result.rb', line 47

def method_missing(method, *args, **opts, &block)
  ChainableResult::Future.new(self, method, args, opts, &block)
end

Class Method Details

.resolve_item(item) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/chainable_result.rb', line 103

def self.resolve_item(item)
  case item
  when ChainableResult then item.value
  when ::Array then ChainableResult::Array.new(item).value
  when ::Hash then ChainableResult::Hash.new(item).value
  else item
  end
end

.sync_with(*results, &block) ⇒ Object



94
95
96
97
# File 'lib/chainable_result.rb', line 94

def self.sync_with(*results, &block)
  # Non-time-traveling, synchronous version of `with` for testing
  ((results.size == 1) ? results.first : results).then(&block)
end

.with(*results, &block) ⇒ Object



90
91
92
# File 'lib/chainable_result.rb', line 90

def self.with(*results, &block)
  ChainableResult.wrap((results.size == 1) ? results.first : results, :then, &block)
end

.with_cache(mode = true) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/chainable_result.rb', line 115

def self.with_cache(mode = true)
  prev = Thread.current[CACHE_MODE_KEY]
  Thread.current[CACHE_MODE_KEY] = mode
  result = yield
  Thread.current[CACHE_MODE_KEY] = prev
  result
end

.wrap(v, method = nil, *args, **opts, &block) ⇒ Object



79
80
81
82
83
84
85
86
87
88
# File 'lib/chainable_result.rb', line 79

def self.wrap(v, method = nil, *args, **opts, &block)
  method ||= block ? :then : :itself
  klass = case v
  when ChainableResult then ChainableResult::Future
  when ::Array then ChainableResult::Array
  when ::Hash then ChainableResult::Hash
  else ChainableResult::Other
  end
  klass.new(v, method, args, opts, &block)
end

Instance Method Details

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/chainable_result.rb', line 51

def respond_to_missing?(method_name, include_private = false)
  true
end

#tap(&block) ⇒ Object



43
44
45
# File 'lib/chainable_result.rb', line 43

def tap(&block)
  ChainableResult::Future.new(self, :tap, &block)
end

#then(&block) ⇒ Object



35
36
37
# File 'lib/chainable_result.rb', line 35

def then(&block)
  ChainableResult::Future.new(self, :then, &block)
end

#to_json(**opts) ⇒ Object



31
32
33
# File 'lib/chainable_result.rb', line 31

def to_json(**opts)
  ChainableResult::Future.new(self, :to_json, [], opts)
end

#valueObject



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/chainable_result.rb', line 11

def value
  if use_cache?
    return @value if @cached
    @cached = true
    @value = resolve_source.send(
      @method,
      *@args.map(&RESOLVE_ITEM),
      **@opts.transform_values(&RESOLVE_ITEM),
      &@block
    )
  else
    resolve_source.send(
      @method,
      *@args.map(&RESOLVE_ITEM),
      **@opts.transform_values(&RESOLVE_ITEM),
      &@block
    )
  end
end

#yield_self(&block) ⇒ Object



39
40
41
# File 'lib/chainable_result.rb', line 39

def yield_self(&block)
  ChainableResult::Future.new(self, :yield_self, &block)
end