class Pakyow::Data::Proxy
@api private
Constants
- IVARS_TO_DUP
Attributes
app[R]
nested_proxies[R]
proxied_calls[R]
source[R]
Public Class Methods
_load(state)
click to toggle source
# File lib/pakyow/data/proxy.rb, line 217 def self._load(state) state = Marshal.load(state) case state[:source] when Sources::Ephemeral ephemeral = state[:app].data.ephemeral(state[:source].source_name) ephemeral.instance_variable_set(:@source, state[:source]) ephemeral else state[:app].data.public_send(state[:source]).apply(state[:proxied_calls]) end end
new(source, subscribers, app)
click to toggle source
# File lib/pakyow/data/proxy.rb, line 22 def initialize(source, subscribers, app) @source, @subscribers, @app = source, subscribers, app @proxied_calls = [] @subscribable = true @nested_proxies = [] end
Public Instance Methods
_dump(_)
click to toggle source
# File lib/pakyow/data/proxy.rb, line 207 def _dump(_) Marshal.dump( { app: @app, source: @source.is_a?(Sources::Ephemeral) ? @source : @source.source_name, proxied_calls: @proxied_calls } ) end
apply(proxied_calls)
click to toggle source
@api private
# File lib/pakyow/data/proxy.rb, line 259 def apply(proxied_calls) proxied_calls.inject(self) { |proxy, proxied_call| if proxied_call[2].any? proxy.public_send(proxied_call[0], *proxied_call[1]) do apply(proxied_call[2]) end else proxy.public_send(proxied_call[0], *proxied_call[1]) end } end
deep_dup()
click to toggle source
Calls superclass method
# File lib/pakyow/data/proxy.rb, line 32 def deep_dup super.tap do |duped| IVARS_TO_DUP.each do |ivar| duped.instance_variable_set(ivar, duped.instance_variable_get(ivar).deep_dup) end end end
method_missing(method_name, *args) { |duped_proxy| ... }
click to toggle source
Calls superclass method
# File lib/pakyow/data/proxy.rb, line 40 def method_missing(method_name, *args, &block) if @source.command?(method_name) dup.tap { |duped_proxy| result = @source.command(method_name).call(*args) { |yielded_result| duped_proxy.instance_variable_set(:@source, yielded_result) yield duped_proxy if block_given? } if @source.respond_to?(:transaction) && @source.transaction? @source.on_commit do @subscribers.did_mutate( @source.source_name, args[0], result ) end else @subscribers.did_mutate( @source.source_name, args[0], result ) end } elsif @source.query?(method_name) || @source.modifier?(method_name) dup.tap { |duped_proxy| nested_calls = [] new_source = if block_given? && @source.block_for_nested_source?(method_name) # In this case a block has been passed that would, without intervention, # be called in context of a source instance. We don't want that, since # it would provide full access to the underlying dataset. Instead the # exposed object should simply be another proxy. local_subscribers, local_app = @subscribers, @app @source.source_from_self.public_send(method_name, *args) { nested_proxy = Proxy.new(self, local_subscribers, local_app) nested_proxy.instance_variable_set(:@proxied_calls, nested_calls) nested_proxy.instance_exec(&block).source.tap do |nested_proxy_source| duped_proxy.nested_proxies << nested_proxy.dup.tap do |finalized_nested_proxy| finalized_nested_proxy.instance_variable_set(:@source, nested_proxy_source) end end } else @source.source_from_self.public_send(method_name, *args).tap do |working_source| working_source.included.each do |_, included_source| nested_proxy = Proxy.new(included_source, @subscribers, @app) duped_proxy.nested_proxies << nested_proxy end end end duped_proxy.instance_variable_set(:@source, new_source) duped_proxy.instance_variable_get(:@proxied_calls) << [ method_name, args, nested_calls ] } else if Array.instance_methods.include?(method_name) && !@source.class.instance_methods.include?(method_name) build_result( @source.to_a.public_send(method_name, *args, &block), method_name, args ) elsif @source.class.instance_methods.include?(method_name) build_result( @source.public_send(method_name, *args, &block), method_name, args ) else super end end end
qualifications()
click to toggle source
# File lib/pakyow/data/proxy.rb, line 230 def qualifications @proxied_calls.inject(@source.qualifications) { |qualifications, proxied_call| qualifications_for_proxied_call = @source.class.qualifications(proxied_call[0]).dup # Populate argument qualifications with argument values. # qualifications_for_proxied_call.each do |qualification_key, qualification_value| if qualification_value.to_s.start_with?("__arg") arg_number = qualification_value.to_s.gsub(/[^0-9]/, "").to_i arg_value = proxied_call[1][arg_number] arg_value = case arg_value when Array arg_value.map { |each_value| @source.class.attributes[qualification_key][each_value] } else @source.class.attributes[qualification_key][arg_value] end qualifications_for_proxied_call[qualification_key] = arg_value end end qualifications.merge(qualifications_for_proxied_call) } end
respond_to_missing?(method_name, include_private = false)
click to toggle source
# File lib/pakyow/data/proxy.rb, line 111 def respond_to_missing?(method_name, include_private = false) return false if method_name == :marshal_dump || method_name == :marshal_load @source.command?(method_name) || @source.query?(method_name) || @source.modifier?(method_name) || @source.respond_to?(method_name, include_private) end
subscribable(boolean)
click to toggle source
# File lib/pakyow/data/proxy.rb, line 197 def subscribable(boolean) tap do @subscribable = boolean end end
subscribable?()
click to toggle source
# File lib/pakyow/data/proxy.rb, line 203 def subscribable? @subscribable == true end
subscribe(subscriber, handler:, payload: nil, &block)
click to toggle source
# File lib/pakyow/data/proxy.rb, line 124 def subscribe(subscriber, handler:, payload: nil, &block) subscriptions = [] if subscribable? subscription = { source: @source.source_name, ephemeral: @source.is_a?(Sources::Ephemeral), handler: handler, payload: payload, qualifications: qualifications, proxy: self } unless subscriptions.include?(subscription) subscriptions << subscription end @nested_proxies.each do |related_proxy| subscriptions.concat( related_proxy.subscribe_related( parent_source: @source, serialized_proxy: self, handler: handler, payload: payload ) ) end end @subscribers.register_subscriptions(subscriptions, subscriber: subscriber, &block) end
to_ary()
click to toggle source
# File lib/pakyow/data/proxy.rb, line 116 def to_ary to_a end
to_json(*)
click to toggle source
# File lib/pakyow/data/proxy.rb, line 120 def to_json(*) @source.to_json end
unsubscribe()
click to toggle source
# File lib/pakyow/data/proxy.rb, line 193 def unsubscribe subscribable(false) end
Private Instance Methods
build_result(value, method_name, args)
click to toggle source
# File lib/pakyow/data/proxy.rb, line 273 def build_result(value, method_name, args) if method_name.to_s.end_with?("?") value else Result.new(value, self, originating_method: method_name, originating_args: args) end end