Class: Caricature::ClrIsolator

Inherits:
Isolator show all
Defined in:
lib/caricature/clr/isolator.rb

Overview

A proxy to CLR objects that records method calls. this implements all the public instance methods of the class when you use it in ruby code When you use it in a CLR class you’re bound to CLR rules and it only overrides the methods that are marked as virtual. We also can’t isolate static or sealed types at the moment.

Instance Attribute Summary

Attributes inherited from Isolator

#descriptor, #isolation, #subject

Instance Method Summary collapse

Methods inherited from Isolator

#build_isolation, #class_name, for, #initialize_isolation

Constructor Details

#initialize(context) ⇒ ClrIsolator

Implementation of the template method that creates an isolator for a class defined in a CLR language.



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/caricature/clr/isolator.rb', line 114

def initialize(context)
  super
  instance = nil
  sklass = context.subject
  unless context.subject.respond_to?(:class_eval)
    sklass = context.subject.class
    instance = context.subject
  end
  @descriptor = ClrClassDescriptor.new sklass
  instance ||= sklass.new unless sklass.to_clr_type.is_abstract
  build_isolation sklass, instance
end

Instance Method Details

#create_isolation_for(subj) ⇒ Object

builds the Isolator class for the specified subject



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/caricature/clr/isolator.rb', line 133

def create_isolation_for(subj)
  members = @descriptor.instance_members
  class_members = @descriptor.class_members
  events = @descriptor.events
  class_events = @descriptor.class_events

  klass = Object.const_set(class_name(subj), Class.new(subj))
  klass.class_eval do

    include Interception

    # access to the proxied subject
    def ___super___
      isolation_context.instance
    end

    def initialize(*args)
      self
    end

    members.each do |mem|
      nm = mem.name.to_s.to_sym
      define_method nm do |*args|
        b = nil
        b = Proc.new { yield } if block_given?
        isolation_context.send_message(nm, mem.return_type, *args, &b)
      end unless nm == :to_string
    end

    class_members.each do |mn|
      mn = mn.name.to_s.to_sym
      define_cmethod mn do |*args|
        b = nil
        b = Proc.new { yield } if block_given?
        isolation_context.send_class_message(mn, nil, *args, &b)
      end
    end
    
   evts = (events + class_events).collect do |evt|
     %w(add remove).inject("") do |res, nm|
       res << "       \ndef \#{\"self.\" unless evt.instance_member?}\#{nm}_\#{evt.event_name}(block)\n  self.isolation_context.\#{nm}_event_subscription('\#{evt.event_name}', :\#{evt.instance_member? ? \"instance\" : \"class\"}, block)\nend\n \n       end_event_definition\n     end\n\n    end.join(\"\\n\")\n\n    klass.class_eval evts\n    \n    #puts evts\n\n  end\n\n  klass\nend\n"

#initialize_messengerObject

initializes the messaging strategy for the isolator



128
129
130
# File 'lib/caricature/clr/isolator.rb', line 128

def initialize_messenger
  @context.messenger = ClrClassMessenger.new @context.expectations, @subject
end