Class: WineOLE::Proxy
- Inherits:
-
Object
show all
- Defined in:
- lib/wineole/proxy.rb
Constant Summary
collapse
- IMPLICIT_CONVERSIONS =
Ruby's implicit-conversion protocol. The interpreter probes these on
arbitrary objects behind the scenes — puts/p and Array() look for
to_ary/to_a, multiple assignment looks for to_ary, string
interpolation and Kernel#String look for to_str, IO methods look
for to_io, &obj looks for to_proc, Integer()/format('%d', _)/
"ab" * _/array indexing look for to_int/to_i, Float() looks for
to_f, File.open looks for to_path, and 1 + _ looks for coerce.
Forwarding these to the remote object turns every puts proxy into a
round trip that ends in DISP_E_UNKNOWNNAME, so they must behave exactly
as they would on a plain Ruby object that doesn't define them:
NoMethodError, and respond_to? == false (which is what stops the
interpreter calling them at all).
%i[
to_ary to_a to_hash to_str to_io to_proc
to_int to_i to_f to_path coerce
].freeze
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
-
#[](*args) ⇒ Object
-
#initialize(client, session_id:, handle:, created:) ⇒ Proxy
constructor
-
#invoke(name, args, named) ⇒ Object
Deliberately bare and public, unlike every other meta-method here (which are ole_-prefixed to avoid shadowing a same-named remote COM member): an explicit escape hatch for the rare case a COM object really does define e.g.
-
#marshal_dump ⇒ Object
-
#method_missing(name, *args) ⇒ Object
-
#ole_const_load ⇒ Object
-
#ole_created? ⇒ Boolean
Was this instance freshly created by connect_or_create's fallback, or attached to something already running? true for .create, false for .connect, whatever the bridge reported for .connect_or_create, and nil for anything derived from another Proxy (e.g. xl.Worksheets) — attach-vs-create isn't a meaningful question for those.
-
#ole_release ⇒ Object
-
#respond_to_missing?(name, _include_private = false) ⇒ Boolean
Constructor Details
#initialize(client, session_id:, handle:, created:) ⇒ Proxy
Returns a new instance of Proxy.
44
45
46
47
48
49
|
# File 'lib/wineole/proxy.rb', line 44
def initialize(client, session_id:, handle:, created:)
@client = client
@ole_session_id = session_id
@ole_handle = handle
@created = created
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
51
52
53
54
55
56
57
|
# File 'lib/wineole/proxy.rb', line 51
def method_missing(name, *args)
return super if IMPLICIT_CONVERSIONS.include?(name)
check_live!
named = args.last.is_a?(Hash) ? args.pop : {}
invoke(name.to_s, args, named)
end
|
Instance Attribute Details
#ole_handle ⇒ Object
Returns the value of attribute ole_handle.
42
43
44
|
# File 'lib/wineole/proxy.rb', line 42
def ole_handle
@ole_handle
end
|
#ole_session_id ⇒ Object
Returns the value of attribute ole_session_id.
42
43
44
|
# File 'lib/wineole/proxy.rb', line 42
def ole_session_id
@ole_session_id
end
|
Class Method Details
.connect(class_name, client) ⇒ Object
11
12
13
14
|
# File 'lib/wineole/proxy.rb', line 11
def self.connect(class_name, client)
handle = client.call('connect', {class_name: class_name})['$ole_ref']
new(client, session_id: client.object_id, handle: handle, created: false)
end
|
.connect_or_create(class_name, client) ⇒ Object
16
17
18
19
|
# File 'lib/wineole/proxy.rb', line 16
def self.connect_or_create(class_name, client)
result = client.call('connect_or_create', {class_name: class_name})
new(client, session_id: client.object_id, handle: result['$ole_ref'], created: result['created'])
end
|
.create(class_name, client) ⇒ Object
6
7
8
9
|
# File 'lib/wineole/proxy.rb', line 6
def self.create(class_name, client)
handle = client.call('create', {class_name: class_name})['$ole_ref']
new(client, session_id: client.object_id, handle: handle, created: true)
end
|
.wrap(client, session_id, ole_ref) ⇒ Object
21
22
23
|
# File 'lib/wineole/proxy.rb', line 21
def self.wrap(client, session_id, ole_ref)
new(client, session_id: session_id, handle: ole_ref, created: nil)
end
|
Instance Method Details
#[](*args) ⇒ Object
63
64
65
66
|
# File 'lib/wineole/proxy.rb', line 63
def [](*args)
check_live!
invoke('', args, {})
end
|
#invoke(name, args, named) ⇒ Object
Deliberately bare and public, unlike every other meta-method here
(which are ole_-prefixed to avoid shadowing a same-named remote COM
member): an explicit escape hatch for the rare case a COM object
really does define e.g. an ole_handle member, matching real Ruby
WIN32OLE's own choice to keep invoke public and unprefixed.
96
97
98
99
100
101
102
103
104
105
|
# File 'lib/wineole/proxy.rb', line 96
def invoke(name, args, named)
check_live!
params = {
handle: @ole_handle,
name: name,
args: args.map { |a| encode(a) },
named: named.transform_values { |v| encode(v) },
}
decode(@client.call('invoke', params))
end
|
#marshal_dump ⇒ Object
87
88
89
|
# File 'lib/wineole/proxy.rb', line 87
def marshal_dump
raise NotSerializableError, 'WineOLE::Proxy references are connection-scoped and cannot be persisted'
end
|
#ole_const_load ⇒ Object
82
83
84
85
|
# File 'lib/wineole/proxy.rb', line 82
def ole_const_load
check_live!
@client.call('const_load', {handle: @ole_handle})
end
|
#ole_created? ⇒ Boolean
Was this instance freshly created by connect_or_create's
fallback, or attached to something already running? true for
.create, false for .connect, whatever the bridge reported for
.connect_or_create, and nil for anything derived from another
Proxy (e.g. xl.Worksheets) — attach-vs-create isn't a meaningful
question for those.
74
75
76
|
# File 'lib/wineole/proxy.rb', line 74
def ole_created?
@created
end
|
#ole_release ⇒ Object
78
79
80
|
# File 'lib/wineole/proxy.rb', line 78
def ole_release
@client.call('release', {handle: @ole_handle})
end
|
#respond_to_missing?(name, _include_private = false) ⇒ Boolean
59
60
61
|
# File 'lib/wineole/proxy.rb', line 59
def respond_to_missing?(name, _include_private = false)
!IMPLICIT_CONVERSIONS.include?(name)
end
|