Class: Raw::Compiler

Inherits:
Object
  • Object
show all
Defined in:
lib/raw/compiler.rb

Overview

The Compiler dynamically generates action methods for the Controllers.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(application) ⇒ Compiler

Initialize the compiler.



20
21
22
23
24
# File 'lib/raw/compiler.rb', line 20

def initialize(application)
  @application = application
  @reloader = Reloader.new(application)
  @templates = []
end

Instance Attribute Details

#reloaderObject

The reloader monitors and reloads code and template files.



16
17
18
# File 'lib/raw/compiler.rb', line 16

def reloader
  @reloader
end

#templatesObject

A collection of the loaded template files.



12
13
14
# File 'lib/raw/compiler.rb', line 12

def templates
  @templates
end

Instance Method Details

#compile(controller, meth) ⇒ Object

This method compiles missing Controller methods. Only handles xxx___super and xxx___format___view methods.



29
30
31
32
33
34
35
36
37
38
39
# File 'lib/raw/compiler.rb', line 29

def compile(controller, meth)
  meth = meth.to_s

  if meth =~ %r{___super$}
    compile_super(controller, meth)
  elsif meth =~ %r{___view$}
    compile_view(controller, meth)
  else
    return false
  end
end

#compile_super(controller, meth) ⇒ Object

Compile the action super-method for the given URI. This super-method calls the action and view sub-methods. The action sub-method is typically provided by the controller.

In a sense, the super-method orchestrates the action and view sub-methods to handle the given URI.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/raw/compiler.rb', line 48

def compile_super(controller, meth)
  action = meth.gsub(%r{___super$}, "")

  Logger.debug "Compiling '#{action}' super-method" if $DBG        

  if controller.action_or_template?(action, Context.current.format)
    
    # This is the actual control super method that calls
    # the action code and the template for this format.
    
    code = lambda do |params|
      @context.format.before_action(self, @context)

      @action = action.to_sym 

      # Call the action sub-method.

      send(action, *params) if respond_to? action
      
      # Call the view sub-method (render the template).
      
      send("#{action}___#{@context.format}___view")

      @context.format.after_action(self, @context)
      
      cache_output()        
    end # lambda
    
    controller.send(:define_method, meth, code)
    controller.send(:private, meth)
    
    return true
  else
    return false
  end
end

#compile_view(controller, meth) ⇒ Object

Compile the view sub-method for the given URI. – The sub-method is always generated, if no template is found it is just a nop method.

TODO: cache the generated files (reuse the cached files to extract error regions) ++



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/raw/compiler.rb', line 94

def compile_view(controller, meth)
  md = meth.match(%r{(.*)___(.*)___view})
  action, format = md[1], md[2]

  format = @application.dispatcher.formats[format]

  Logger.debug "Compiling '#{action}' view sub-method [format: #{format}]" if $DBG        

  unless controller.instance_methods.include? meth
    # The view method is missing. The Compiler will try to 
    # use a template or generate an empty view method.
    
    template = nil
    
    if path = controller.template_path(action, format)
      # Keep a ref of this template for the reloader.
      
      @templates = @templates.push(path).uniq
      
      # Read the template source.
              
      template = File.read(path)

      # Apply the template filters.
      
      unless template.blank? 
        template = format.filter_template(template)
      end
    end

    controller.class_eval <<-EOCODE # , path, 0 
      def #{meth}
        #{template}
      end
    EOCODE
    
    controller.send(:private, meth)
  end
      
  return true
end