Class: VirtualKeywords::Virtualizer

Inherits:
Object
  • Object
show all
Defined in:
lib/virtual_keywords/virtualizer.rb

Overview

Object that virtualizes keywords.

Instance Method Summary collapse

Constructor Details

#initialize(input_hash) ⇒ Virtualizer

Initialize a Virtualizer

Arguments:

A Hash with the following arguments (all optional):
for_classes: (Array[Class]) an array of classes. All methods of objects
             created from the given classes will be virtualized
             (optional, the default is an empty Array).
for_instances: (Array[Object]) an array of object. All of these objects'
               methods will be virtualized
               (optional, the default is an empty Array).
for subclasses_of: (Array[Class]) an array of classes. All methods of
                   objects created from the given classes' subclasses
                   (but NOT those from the given classes) will be
                   virtualized.
if_rewriter: (IfRewriter) the SexpProcessor descendant that
             rewrites "if"s in methods (optional, the default is
             IfRewriter.new).
and_rewriter: (AndRewriter) the SexpProcessor descendant that
              rewrites "and"s in methods (optional, the default is
              AndRewriter.new).
or_rewriter: (OrRewriter) the SexpProcessor descendant that
              rewrites "or"s in methods (optional, the default is
              OrRewriter.new).
sexp_processor: (SexpProcessor) the sexp_processor that can turn
                ParseTree results into sexps (optional, the default is
                SexpProcessor.new).
sexp_stringifier: (SexpStringifier) an object that can turn sexps
                  back into Ruby code (optional, the default is
                  SexpStringifier.new).
rewritten_keywords: (RewrittenKeywords) a repository for keyword
                    replacement lambdas (optional, the default is
                    REWRITTEN_KEYWORDS).


132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/virtual_keywords/virtualizer.rb', line 132

def initialize(input_hash)
  @for_classes = input_hash[:for_classes] || []
  @for_instances = input_hash[:for_instances] || []
  @for_subclasses_of = input_hash[:for_subclasses_of] || []
  @if_rewriter = input_hash[:if_rewriter] || IfRewriter.new
  @and_rewriter = input_hash[:and_rewriter] || AndRewriter.new
  @or_rewriter = input_hash[:or_rewriter] || OrRewriter.new
  @sexp_processor = input_hash[:sexp_processor] || SexpProcessor.new
  @sexp_stringifier = input_hash[:sexp_stringifier] || SexpStringifier.new
  @rewritten_keywords =
      input_hash[:rewritten_keywords] || REWRITTEN_KEYWORDS
end

Instance Method Details

#rewrite_methods_of_class(klass, keyword, rewriter, block) ⇒ Object

Helper method to rewrite all methods of objects from a class.

Arguments:

klass: (Class) the class whose methods will be rewritten.
keyword: (Symbol) the keyword to virtualize.
rewriter: (SexpProcessor) the object that will do the rewriting.
block: (Proc) the lambda that will replace the keyword.


183
184
185
186
187
188
189
190
191
# File 'lib/virtual_keywords/virtualizer.rb', line 183

def rewrite_methods_of_class(klass, keyword, rewriter, block)
  @rewritten_keywords.register_lambda_for_class(klass, keyword, block)        

  methods = ClassReflection.instance_methods_of klass
  methods.each do |name, translated|
    new_code = rewritten_code(translated, rewriter)
    ClassReflection.install_method_on_class(klass, new_code)
  end
end

#rewrite_methods_of_instance(instance, keyword, rewriter, block) ⇒ Object

Helper method to rewrite all methods of an object.

Arguments:

instance: (Object) the object whose methods will be rewritten.
keyword: (Symbol) the keyword to virtualize.
rewriter: (SexpProcessor) the object that will do the rewriting.
block: (Proc) the lambda that will replace the keyword.


166
167
168
169
170
171
172
173
174
# File 'lib/virtual_keywords/virtualizer.rb', line 166

def rewrite_methods_of_instance(instance, keyword, rewriter, block)
  @rewritten_keywords.register_lambda_for_object(instance, keyword, block)

  methods = ClassReflection.instance_methods_of instance.class
  methods.each do |name, translated|
    new_code = rewritten_code(translated, rewriter)
    ClassReflection.install_method_on_instance(instance, new_code)
  end
end

#rewritten_code(translated, rewriter) ⇒ Object

Helper method to rewrite code.

Arguments:

translated: (Array) the output of ParseTree.translate on the original
            code
rewriter: (SexpProcessor) the object that will rewrite the sexp, to
          virtualize the keywords.


152
153
154
155
156
157
# File 'lib/virtual_keywords/virtualizer.rb', line 152

def rewritten_code(translated, rewriter)
  sexp = @sexp_processor.process(
      VirtualKeywords.deep_copy_array(translated))
  new_code = @sexp_stringifier.stringify(
      rewriter.process(sexp))
end

#virtual_and(&block) ⇒ Object

Rewrite “and” expressions.

Arguments:

&block: The block that will replace "and"s in the objects being
        virtualized


228
229
230
# File 'lib/virtual_keywords/virtualizer.rb', line 228

def virtual_and(&block)
  virtualize_keyword(:and, @and_rewriter, block)
end

#virtual_if(&block) ⇒ Object

Rewrite “if” expressions.

Arguments:

&block: The block that will replace "if"s in the objects being
        virtualized


219
220
221
# File 'lib/virtual_keywords/virtualizer.rb', line 219

def virtual_if(&block)
  virtualize_keyword(:if, @if_rewriter, block)
end

#virtual_or(&block) ⇒ Object

Rewrite “or” expressions.

Arguments:

&block: The block that will replace "or"s in the objects being
        virtualized


237
238
239
# File 'lib/virtual_keywords/virtualizer.rb', line 237

def virtual_or(&block)
  virtualize_keyword(:or, @or_rewriter, block)
end

#virtualize_keyword(keyword, rewriter, block) ⇒ Object

Helper method to virtualize a keyword (rewrite with the given block)

Arguments:

keyword: (Symbol) the keyword to virtualize.
rewriter: (SexpProcessor) the object that will do the rewriting.
block: (Proc) the lambda that will replace the keyword.


199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/virtual_keywords/virtualizer.rb', line 199

def virtualize_keyword(keyword, rewriter, block)
  @for_instances.each do |instance|
    rewrite_methods_of_instance(instance, keyword, rewriter, block)  
  end 

  @for_classes.each do |klass|
    rewrite_methods_of_class(klass, keyword, rewriter, block)
  end

  subclasses = ClassReflection.subclasses_of_classes @for_subclasses_of
  subclasses.each do |subclass|
    rewrite_methods_of_class(subclass, keyword, rewriter, block)
  end
end