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 =
method(: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



37
38
39
# File 'lib/chainable_result.rb', line 37

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

Class Method Details

.resolve_item(item) ⇒ Object



86
87
88
89
90
91
92
93
# File 'lib/chainable_result.rb', line 86

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

.with(*results, &block) ⇒ Object



80
81
82
# File 'lib/chainable_result.rb', line 80

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

.with_cache(mode = true) ⇒ Object



98
99
100
101
102
103
104
# File 'lib/chainable_result.rb', line 98

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



69
70
71
72
73
74
75
76
77
78
# File 'lib/chainable_result.rb', line 69

def self.wrap(v, method = nil, *args, **opts, &block)
  method ||= block ? :then : :itself
  klass = case v
  when ChainableResult then return v # don't wrap, exit early
  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)


41
42
43
# File 'lib/chainable_result.rb', line 41

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

#tap(&block) ⇒ Object



33
34
35
# File 'lib/chainable_result.rb', line 33

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

#then(&block) ⇒ Object



25
26
27
# File 'lib/chainable_result.rb', line 25

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

#to_json(**opts) ⇒ Object



21
22
23
# File 'lib/chainable_result.rb', line 21

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

#valueObject



11
12
13
14
15
16
17
18
19
# File 'lib/chainable_result.rb', line 11

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

#yield_self(&block) ⇒ Object



29
30
31
# File 'lib/chainable_result.rb', line 29

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