DeepConnect 0.4.06
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/deep-connect.rb +83 -0
- data/lib/deep-connect/accepter.rb +64 -0
- data/lib/deep-connect/class-spec-space.rb +652 -0
- data/lib/deep-connect/conf.rb +48 -0
- data/lib/deep-connect/cron.rb +91 -0
- data/lib/deep-connect/deep-fork.rb +70 -0
- data/lib/deep-connect/deep-mq.rb +62 -0
- data/lib/deep-connect/deep-space.rb +403 -0
- data/lib/deep-connect/evaluator.rb +149 -0
- data/lib/deep-connect/event.rb +551 -0
- data/lib/deep-connect/exceptions.rb +38 -0
- data/lib/deep-connect/future.rb +67 -0
- data/lib/deep-connect/organizer.rb +378 -0
- data/lib/deep-connect/port.rb +151 -0
- data/lib/deep-connect/reference.rb +422 -0
- data/lib/deep-connect/serialize.rb +127 -0
- data/lib/deep-connect/session.rb +348 -0
- data/lib/deep-connect/version.rb +8 -0
- metadata +86 -0
@@ -0,0 +1,151 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# port.rb -
|
4
|
+
# Copyright (C) 1996-2010 Keiju ISHITSUKA
|
5
|
+
# (Penta Advanced Labrabries, Co.,Ltd)
|
6
|
+
#
|
7
|
+
# --
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
|
12
|
+
require "deep-connect/event"
|
13
|
+
|
14
|
+
module DeepConnect
|
15
|
+
class Port
|
16
|
+
|
17
|
+
PACK_n_SIZE = [1].pack("n").size
|
18
|
+
PACK_N_SIZE = [1].pack("N").size
|
19
|
+
|
20
|
+
def initialize(sock)
|
21
|
+
@io = sock
|
22
|
+
@peeraddr = @io.peeraddr
|
23
|
+
@session = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def close
|
27
|
+
@io.close
|
28
|
+
end
|
29
|
+
|
30
|
+
def shutdown_reading
|
31
|
+
@io.shutdown(Socket::SHUT_RD)
|
32
|
+
end
|
33
|
+
|
34
|
+
def addr
|
35
|
+
@io.addr
|
36
|
+
end
|
37
|
+
|
38
|
+
def peeraddr
|
39
|
+
@peeraddr
|
40
|
+
end
|
41
|
+
|
42
|
+
def attach(session)
|
43
|
+
@session = session
|
44
|
+
end
|
45
|
+
|
46
|
+
def import2
|
47
|
+
# puts "IMPORT: start0"
|
48
|
+
# sz = read(PACK_N_SIZE).unpack("N").first
|
49
|
+
# bin = read(sz)
|
50
|
+
a = Marshal.load(@io)
|
51
|
+
begin
|
52
|
+
# ijijć, ōŃňů|ůČ??8Ĺī??-ĢĪ.
|
53
|
+
ev = Event.materialize(@session, a.first, *a)
|
54
|
+
rescue
|
55
|
+
p $!, $@
|
56
|
+
raise
|
57
|
+
end
|
58
|
+
puts "IMPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
|
59
|
+
ev
|
60
|
+
end
|
61
|
+
|
62
|
+
def import
|
63
|
+
# puts "IMPORT: start0"
|
64
|
+
sz = read(PACK_N_SIZE).unpack("N").first
|
65
|
+
bin = read(sz)
|
66
|
+
begin
|
67
|
+
a = Marshal.load(bin)
|
68
|
+
rescue
|
69
|
+
p bin
|
70
|
+
p $!, $@
|
71
|
+
raise
|
72
|
+
end
|
73
|
+
begin
|
74
|
+
# ここで, ネットワーク通信発生する可能性あり.
|
75
|
+
ev = Event.materialize(@session, a.first, *a)
|
76
|
+
rescue
|
77
|
+
p $!, $@
|
78
|
+
raise
|
79
|
+
end
|
80
|
+
puts "IMPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
|
81
|
+
ev
|
82
|
+
end
|
83
|
+
|
84
|
+
def export2(ev)
|
85
|
+
puts "EXPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
|
86
|
+
bin = Marshal.dump(ev.serialize, @io)
|
87
|
+
# size = bin.size
|
88
|
+
|
89
|
+
# packet = [size].pack("N")+bin
|
90
|
+
# write(packet)
|
91
|
+
puts "EXPORT: finsh" if Conf.MESSAGE_DISPLAY
|
92
|
+
end
|
93
|
+
|
94
|
+
def export(ev)
|
95
|
+
puts "EXPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
|
96
|
+
begin
|
97
|
+
bin = Marshal.dump(ev.serialize)
|
98
|
+
rescue
|
99
|
+
puts "Exception Rised: #{$!}"
|
100
|
+
puts $@
|
101
|
+
p ev.serialize
|
102
|
+
raise
|
103
|
+
end
|
104
|
+
size = bin.size
|
105
|
+
|
106
|
+
packet = [size].pack("N")+bin
|
107
|
+
write(packet)
|
108
|
+
puts "EXPORT: finsh" if Conf.MESSAGE_DISPLAY
|
109
|
+
end
|
110
|
+
|
111
|
+
# def import
|
112
|
+
# sz = read(PACK_N_SIZE).unpack("N").first
|
113
|
+
# bin = read(sz).unpack("a#{sz}")
|
114
|
+
# a = Marshal.load(bin.first)
|
115
|
+
# ev = Event.materialize(@session, a.first, *a)
|
116
|
+
# puts "IMPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
|
117
|
+
# ev
|
118
|
+
# end
|
119
|
+
|
120
|
+
# def export(ev)
|
121
|
+
# puts "EXPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
|
122
|
+
# s = Marshal.dump(ev.serialize)
|
123
|
+
# size = s.size
|
124
|
+
# packet = [size, s].pack("Na#{size}")
|
125
|
+
# write(packet)
|
126
|
+
# end
|
127
|
+
|
128
|
+
def read(n)
|
129
|
+
begin
|
130
|
+
packet = @io.read(n)
|
131
|
+
fail EOFError, "socket closed" unless packet
|
132
|
+
# DC::Raise ProtocolError unless packet.size == n
|
133
|
+
packet
|
134
|
+
rescue Errno::ECONNRESET, EOFError
|
135
|
+
puts "WARN: read中に[#{peeraddr.join(', ')}]の接続が切れました"
|
136
|
+
DC::Raise DisconnectClient, peeraddr
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def write(packet)
|
141
|
+
begin
|
142
|
+
@io.write(packet)
|
143
|
+
# @io.flush
|
144
|
+
rescue Errno::ECONNRESET
|
145
|
+
puts "WARN: write中に[#{peeraddr.join(', ')}]の接続が切れました"
|
146
|
+
DC::Raise DisconnectClient, peeraddr
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
@@ -0,0 +1,422 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# reference.rb -
|
4
|
+
# Copyright (C) 1996-2010 Keiju ISHITSUKA
|
5
|
+
# (Penta Advanced Labrabries, Co.,Ltd)
|
6
|
+
#
|
7
|
+
# --
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
|
12
|
+
require "deep-connect/class-spec-space"
|
13
|
+
|
14
|
+
module DeepConnect
|
15
|
+
class Reference
|
16
|
+
|
17
|
+
preserved = [
|
18
|
+
:__id__, :object_id, :__send__, :public_send, :respond_to?, :send,
|
19
|
+
:instance_eval, :instance_exec, :extend, "!".intern
|
20
|
+
]
|
21
|
+
instance_methods.each do |m|
|
22
|
+
next if preserved.include?(m.intern)
|
23
|
+
alias_method "__deep_connect_org_#{m}", m
|
24
|
+
undef_method m
|
25
|
+
end
|
26
|
+
|
27
|
+
# session ローカルなプロキシを生成
|
28
|
+
# [クラス名, 値]
|
29
|
+
# [クラス名, ローカルSESSION, 値]
|
30
|
+
def Reference.serialize(deep_space, value, spec = nil)
|
31
|
+
if spec
|
32
|
+
return Reference.serialize_with_spec(deep_space, value, spec)
|
33
|
+
end
|
34
|
+
|
35
|
+
if value.__deep_connect_reference?
|
36
|
+
if deep_space == value.deep_space
|
37
|
+
[value.__deep_connect_real_class, value.csid, value.peer_id, :PEER_OBJECT]
|
38
|
+
else
|
39
|
+
uuid = value.deep_space.peer_uuid.dup
|
40
|
+
if uuid[0] == "127.0.0.1" || uuid[0] == "::ffff:127.0.0.1"
|
41
|
+
uuid[0] = :SAME_UUIDADDR
|
42
|
+
end
|
43
|
+
|
44
|
+
[value.__deep_connect_real_class, value.csid, value.peer_id, uuid]
|
45
|
+
end
|
46
|
+
else
|
47
|
+
case value
|
48
|
+
when *Organizer::immutable_classes
|
49
|
+
[value.__deep_connect_real_class, value.__deep_connect_real_class.name, value]
|
50
|
+
else
|
51
|
+
object_id = deep_space.set_root(value)
|
52
|
+
csid = deep_space.my_csid_of(value)
|
53
|
+
[Reference, csid, object_id]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def Reference.serialize_with_spec(deep_space, value, spec)
|
59
|
+
if value.__deep_connect_reference?
|
60
|
+
if deep_space == value.deep_space
|
61
|
+
[value.__deep_connect_real_class, value.csid, value.peer_id, :PEER_OBJECT]
|
62
|
+
else
|
63
|
+
uuid = value.deep_space.peer_uuid.dup
|
64
|
+
if uuid[0] == "127.0.0.1" || uuid[0] == "::ffff:127.0.0.1"
|
65
|
+
uuid[0] = :SAME_UUIDADDR
|
66
|
+
end
|
67
|
+
|
68
|
+
[value.__deep_connect_real_class, value.csid, value.peer_id, uuid]
|
69
|
+
end
|
70
|
+
elsif Organizer::absolute_immutable_classes.include?(value.class)
|
71
|
+
[value.__deep_connect_real_class, value.__deep_connect_real_class.name, value]
|
72
|
+
else
|
73
|
+
case spec
|
74
|
+
when MethodSpec::DefaultParamSpec
|
75
|
+
Reference.serialize(deep_space, value)
|
76
|
+
when MethodSpec::RefParamSpec
|
77
|
+
object_id = deep_space.set_root(value)
|
78
|
+
csid = deep_space.my_csid_of(value)
|
79
|
+
[Reference, csid, object_id]
|
80
|
+
when MethodSpec::ValParamSpec
|
81
|
+
serialize_val(deep_space, value, spec)
|
82
|
+
when MethodSpec::DValParamSpec
|
83
|
+
# 第2引数意味なし
|
84
|
+
[value.__deep_connect_real_class, value.__deep_connect_real_class.name, value]
|
85
|
+
else
|
86
|
+
raise ArgumentError,
|
87
|
+
"argument is only specified(#{MethodSpec::ARG_SPEC.join(', ')})(#{spec})"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def Reference.serialize_val(deep_space, value, spec)
|
93
|
+
case value
|
94
|
+
when *Organizer::immutable_classes
|
95
|
+
[value.__deep_connect_real_class, value.__deep_connect_real_class.name, value]
|
96
|
+
else
|
97
|
+
[:VAL, value.__deep_connect_real_class.name,
|
98
|
+
[value.__deep_connect_real_class, value.deep_connect_serialize_val(deep_space)]]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def Reference.materialize(deep_space, type, csid, object_id, uuid=nil)
|
103
|
+
if type == Reference
|
104
|
+
if uuid
|
105
|
+
if uuid == :PEER_OBJECT
|
106
|
+
deep_space.root(object_id)
|
107
|
+
else
|
108
|
+
if uuid[0] == :SAME_UUIDADDR
|
109
|
+
uuid[0] = deep_space.peer_uuid[0].dup
|
110
|
+
end
|
111
|
+
peer_deep_space = deep_space.organizer.deep_space(uuid)
|
112
|
+
peer_deep_space.register_root_to_peer(object_id)
|
113
|
+
type.new(peer_deep_space, csid, object_id)
|
114
|
+
end
|
115
|
+
else
|
116
|
+
type.new(deep_space, csid, object_id)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
if type == :VAL
|
120
|
+
materialize_val(deep_space, type,
|
121
|
+
csid, object_id[0], object_id[1])
|
122
|
+
else
|
123
|
+
# 即値
|
124
|
+
object_id
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def Reference.materialize_val(deep_space, type, csid, klass, value)
|
130
|
+
klass.deep_connect_materialize_val(deep_space, value)
|
131
|
+
end
|
132
|
+
|
133
|
+
# def Reference.register(deep_space, o)
|
134
|
+
# deep_space.peer.set_root(o)
|
135
|
+
# Reference.new(session, o.id)
|
136
|
+
# end
|
137
|
+
|
138
|
+
def Reference.new(deep_space, csid, peer_id)
|
139
|
+
if r = deep_space.import_reference(peer_id)
|
140
|
+
return r
|
141
|
+
end
|
142
|
+
r = super
|
143
|
+
deep_space.register_import_reference(r)
|
144
|
+
r
|
145
|
+
end
|
146
|
+
|
147
|
+
def initialize(deep_space, csid, peer_id)
|
148
|
+
@deep_space = deep_space
|
149
|
+
@csid = csid
|
150
|
+
@peer_id = peer_id
|
151
|
+
end
|
152
|
+
|
153
|
+
attr_reader :deep_space
|
154
|
+
alias deepspace deep_space
|
155
|
+
attr_reader :csid
|
156
|
+
attr_reader :peer_id
|
157
|
+
|
158
|
+
def peer
|
159
|
+
@deep_space.root(@peer_id)
|
160
|
+
end
|
161
|
+
|
162
|
+
def release
|
163
|
+
@deep_space.deregister_import_reference_id(self)
|
164
|
+
end
|
165
|
+
|
166
|
+
# TO_METHODS = [:to_ary, :to_str, :to_int, :to_regexp]
|
167
|
+
# TO_METHODS = [:to_ary, :to_str, :to_int, :to_regexp, :to_splat]
|
168
|
+
|
169
|
+
def method_missing(method, *args, &block)
|
170
|
+
puts "SEND MESSAGE: #{self.inspect} #{method.id2name}" if Conf.DISPLAY_MESSAGE_TRACE
|
171
|
+
|
172
|
+
# if TO_METHODS.include?(method)
|
173
|
+
# return self.dc_dup.send(method)
|
174
|
+
# end
|
175
|
+
begin
|
176
|
+
if iterator?
|
177
|
+
@deep_space.session.send_to(self, method, args, &block)
|
178
|
+
else
|
179
|
+
@deep_space.session.send_to(self, method, args)
|
180
|
+
end
|
181
|
+
# rescue NoMethodError
|
182
|
+
# p $@
|
183
|
+
# p $!
|
184
|
+
# super
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def asynchronus_send_with_callback(method, *args, &callback)
|
189
|
+
@deep_space.session.asyncronus_send_to(self, method, args, callback)
|
190
|
+
end
|
191
|
+
alias asynchronus_send asynchronus_send_with_callback
|
192
|
+
|
193
|
+
# def peer_to_s
|
194
|
+
# @deep_space.session.send_to(self, :to_s)
|
195
|
+
# end
|
196
|
+
|
197
|
+
# def peer_inspect
|
198
|
+
# @deep_space.session.send_to(self, :inspect)
|
199
|
+
# end
|
200
|
+
|
201
|
+
# def peer_class
|
202
|
+
# @deep_space.session.send_to(self, :class)
|
203
|
+
# end
|
204
|
+
|
205
|
+
# def to_s
|
206
|
+
# @deep_space.session.send_to(self, :to_s)
|
207
|
+
# end
|
208
|
+
|
209
|
+
# def to_a
|
210
|
+
# a = []
|
211
|
+
# @deep_space.session.send_to(self, :to_a).each{|e| a.push e}
|
212
|
+
# a
|
213
|
+
# end
|
214
|
+
|
215
|
+
# def =~(other)
|
216
|
+
# @deep_space.session.send_to(self, :=~, other)
|
217
|
+
# end
|
218
|
+
|
219
|
+
# def ===(other)
|
220
|
+
# @deep_space.session.send_to(self, :===, other)
|
221
|
+
# end
|
222
|
+
|
223
|
+
# def id
|
224
|
+
# @deep_space.session.send_to(self, :id)
|
225
|
+
# end
|
226
|
+
|
227
|
+
# def coerce(other)
|
228
|
+
# return other, peer
|
229
|
+
# end
|
230
|
+
|
231
|
+
def __deep_connect_reference?
|
232
|
+
true
|
233
|
+
end
|
234
|
+
alias dc_reference? __deep_connect_reference?
|
235
|
+
|
236
|
+
def __deep_connect_real_class
|
237
|
+
Reference
|
238
|
+
end
|
239
|
+
|
240
|
+
class UndefinedClass;end
|
241
|
+
|
242
|
+
def peer_class
|
243
|
+
return @peer_class if @peer_class
|
244
|
+
begin
|
245
|
+
@peer_class = self.class.dc_deep_copy
|
246
|
+
rescue
|
247
|
+
@peer_class = UndefinedClass
|
248
|
+
end
|
249
|
+
@peer_class
|
250
|
+
end
|
251
|
+
|
252
|
+
def respond_to?(m, include_private = false)
|
253
|
+
# m = m.intern
|
254
|
+
# if m != :to_ary && super
|
255
|
+
# return true
|
256
|
+
# end
|
257
|
+
return true if super
|
258
|
+
return @deep_space.session.send_to(self, :respond_to?, [m, include_private])
|
259
|
+
end
|
260
|
+
|
261
|
+
# ここは, オブジェクトの同値性を用いていない
|
262
|
+
# def ==(obj)
|
263
|
+
# return true if obj.equal?(self)
|
264
|
+
#
|
265
|
+
## self.deep_connect_copy == obj
|
266
|
+
# false
|
267
|
+
# end
|
268
|
+
def ==(obj)
|
269
|
+
obj.__deep_connect_reference? &&
|
270
|
+
@deep_space == obj.deep_space &&
|
271
|
+
@peer_id == obj.peer_id
|
272
|
+
end
|
273
|
+
|
274
|
+
alias eql? ==
|
275
|
+
|
276
|
+
def equal?(obj)
|
277
|
+
self.object_id == obj.object_id
|
278
|
+
end
|
279
|
+
|
280
|
+
def hash
|
281
|
+
@deep_space.object_id ^ @peer_id
|
282
|
+
end
|
283
|
+
|
284
|
+
def kind_of?(klass)
|
285
|
+
if klass.__deep_connect_reference?
|
286
|
+
@deep_space.session.send_to(self, :kind_of?, klass)
|
287
|
+
else
|
288
|
+
self.peer_class <= klass
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def nil?
|
293
|
+
false
|
294
|
+
end
|
295
|
+
|
296
|
+
# def ===(other)
|
297
|
+
# if other.__deep_connect_reference?
|
298
|
+
# @deep_space.session.send_to(self, :===, other)
|
299
|
+
# else
|
300
|
+
# case other
|
301
|
+
# when Class
|
302
|
+
# self.peer_class <= klass
|
303
|
+
# end
|
304
|
+
# end
|
305
|
+
# end
|
306
|
+
|
307
|
+
# def marshal_dump
|
308
|
+
# Reference.serialize(@deep_space, self)
|
309
|
+
# end
|
310
|
+
|
311
|
+
# def marshal_load(obj)
|
312
|
+
# Reference.materialize(
|
313
|
+
# end
|
314
|
+
|
315
|
+
# def marshal_load(obj)
|
316
|
+
# Reference.materialize(
|
317
|
+
# end
|
318
|
+
|
319
|
+
# def to_ary
|
320
|
+
# if respond_to?(:to_ary)
|
321
|
+
# p "AAAAAAA"
|
322
|
+
# self.dc_dup.to_ary
|
323
|
+
# p "BBBBBBBB"
|
324
|
+
# else
|
325
|
+
# # raise NoMethodError.new("undefined method `to_ary' for #{self}@@@", :to_ary)
|
326
|
+
# raise NoMethodError, "to_ary"
|
327
|
+
# end
|
328
|
+
# end
|
329
|
+
|
330
|
+
# def to_str
|
331
|
+
# if respond_to?(:to_str)
|
332
|
+
# self.dc_dup.to_str
|
333
|
+
# end
|
334
|
+
# end
|
335
|
+
|
336
|
+
# def to_a
|
337
|
+
# self.dc_dup.to_a
|
338
|
+
# end
|
339
|
+
|
340
|
+
def to_s(force = false)
|
341
|
+
if !force && /deep-connect/ =~ caller(1).first
|
342
|
+
unless /deep-connect\/test/ =~ caller(1).first
|
343
|
+
return __deep_connect_org_to_s
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
if @deep_space.status == :SERVICING
|
348
|
+
@deep_space.session.send_to(self, :to_s)
|
349
|
+
else
|
350
|
+
"(no service)"
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def inspect(force = false)
|
355
|
+
if !force && /deep-connect/ =~ caller(1).first
|
356
|
+
unless /deep-connect\/test/ =~ caller(1).first
|
357
|
+
return sprintf("<DC::Ref: deep_space=%s csid=%s id=%x>",
|
358
|
+
@deep_space.to_s,
|
359
|
+
@csid,
|
360
|
+
@peer_id)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
if Conf.DEBUG_REFERENCE
|
365
|
+
sprintf("<DC::Ref[deep_space=%s csid=%s id=%x]: %s>",
|
366
|
+
@deep_space.to_s,
|
367
|
+
@csid,
|
368
|
+
@peer_id,
|
369
|
+
to_s)
|
370
|
+
else
|
371
|
+
sprintf("<DC::Ref: %s>", to_s(true))
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def peer_inspect
|
376
|
+
begin
|
377
|
+
@deep_space.session.send_to(self, :inspect)
|
378
|
+
rescue SessionServiceStopped
|
379
|
+
sprintf("<DC::Ref[deep_space=%s csid=%s id=%x]: %s>",
|
380
|
+
@deep_space.to_s,
|
381
|
+
@csid,
|
382
|
+
@peer_id,
|
383
|
+
"(service stoped)")
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
def my_inspect
|
388
|
+
__deep_connect_org_inspect
|
389
|
+
end
|
390
|
+
|
391
|
+
def deep_connect_dup
|
392
|
+
@deep_space.session.send_to(self, :deep_connect_dup)
|
393
|
+
end
|
394
|
+
alias dc_dup deep_connect_dup
|
395
|
+
|
396
|
+
def deep_connect_deep_copy
|
397
|
+
@deep_space.session.send_to(self, :deep_connect_deep_copy)
|
398
|
+
end
|
399
|
+
alias dc_deep_copy deep_connect_deep_copy
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
class Object
|
404
|
+
def __deep_connect_reference?
|
405
|
+
false
|
406
|
+
end
|
407
|
+
alias dc_reference? __deep_connect_reference?
|
408
|
+
|
409
|
+
def __deep_connect_real_class
|
410
|
+
self.class
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
class Module
|
415
|
+
def ===(other)
|
416
|
+
other.kind_of?(self)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
|
421
|
+
|
422
|
+
|