Class: Knj::Eruby

Inherits:
Object show all
Defined in:
lib/knj/eruby.rb

Defined Under Namespace

Classes: Handler

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Eruby

Returns a new instance of Eruby.



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/knj/eruby.rb', line 4

def initialize(args = {})
  @args = args
  
  require "tmpdir"
  @tmpdir = "#{Dir.tmpdir}/knj_erb"
  Dir.mkdir(@tmpdir, 0777) if !File.exists?(@tmpdir)
  
  
  #This argument can be used if a shared cache should be used to speed up performance.
  if @args[:cache_hash]
    @cache = @args[:cache_hash]
  else
    @cache = {}
  end
  
  if RUBY_PLATFORM == "java" or RUBY_ENGINE == "rbx"
    @cache_mode = :code_eval
    #@cache_mode = :compile_knj
  elsif RUBY_VERSION.slice(0..2) == "1.9" and RubyVM::InstructionSequence.respond_to?(:compile_file)
    @cache_mode = :inseq
    #@cache_mode = :compile_knj
  end
  
  if @cache_mode == :compile_knj
    require "#{$knjpath}compiler"
    @compiler = Knj::Compiler.new(:cache_hash => @cache)
  end
  
  self.reset_headers
  self.reset_connects
end

Instance Attribute Details

#connectsObject (readonly)

Returns the value of attribute connects.



2
3
4
# File 'lib/knj/eruby.rb', line 2

def connects
  @connects
end

#cookiesObject (readonly)

Returns the value of attribute cookies.



2
3
4
# File 'lib/knj/eruby.rb', line 2

def cookies
  @cookies
end

#errorObject (readonly)

Returns the value of attribute error.



2
3
4
# File 'lib/knj/eruby.rb', line 2

def error
  @error
end

#fcgiObject (readonly)

Returns the value of attribute fcgi.



2
3
4
# File 'lib/knj/eruby.rb', line 2

def fcgi
  @fcgi
end

#headersObject (readonly)

Returns the value of attribute headers.



2
3
4
# File 'lib/knj/eruby.rb', line 2

def headers
  @headers
end

Instance Method Details

#connect(signal, &block) ⇒ Object



136
137
138
139
# File 'lib/knj/eruby.rb', line 136

def connect(signal, &block)
  @connects[signal] = [] if !@connects.key?(signal)
  @connects[signal] << block
end


132
133
134
# File 'lib/knj/eruby.rb', line 132

def cookie(cookie_data)
  @cookies << cookie_data
end

#destroyObject



81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/knj/eruby.rb', line 81

def destroy
  @connects.clear if @connects.is_a?(Hash)
  @headers.clear if @headers.is_a?(Array)
  @cookies.clear if @cookies.is_a?(Array)
  
  @cache.clear if @cache.is_a?(Hash) and @args and !@args.key?(:cache_hash)
  @args.clear if @args.is_a?(Hash)
  @args = nil
  @cache = nil
  @connects = nil
  @headers = nil
  @cookies = nil
end

#handle_error(e) ⇒ Object

This method will handle an error without crashing simply adding the error to the print-queue.



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/knj/eruby.rb', line 201

def handle_error(e)
  begin
    if @connects and @connects.key?("error")
      @connects["error"].each do |block|
        block.call(e)
      end
    end
  rescue SystemExit => e
    exit
  rescue Exception => e
    #An error occurred while trying to run the on-error-block - show this as an normal error.
    print "\n\n<pre>\n\n"
    print "<b>#{Knj::Web.html(e.class.name)}: #{Knj::Web.html(e.message)}</b>\n\n"
    
    #Lets hide all the stuff in what is not the users files to make it easier to debug.
    bt = e.backtrace
    #to = bt.length - 9
    #bt = bt[0..to]
    
    bt.each do |line|
      print Knj::Web.html(line) + "\n"
    end
    
    print "</pre>"
  end
  
  print "\n\n<pre>\n\n"
  print "<b>#{Knj::Web.html(e.class.name)}: #{Knj::Web.html(e.message)}</b>\n\n"
  
  e.backtrace.each do |line|
    print Knj::Web.html(line) + "\n"
  end
  
  print "</pre>"
end

#has_status_header?Boolean

Returns:

  • (Boolean)


111
112
113
114
115
116
117
# File 'lib/knj/eruby.rb', line 111

def has_status_header?
  @headers.each do |header|
    return true if header[0] == "Status"
  end
  
  return false
end

#header(key, value) ⇒ Object



128
129
130
# File 'lib/knj/eruby.rb', line 128

def header(key, value)
  @headers << [key, value]
end

#import(filename) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
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
# File 'lib/knj/eruby.rb', line 36

def import(filename)
  @error = false
  Dir.mkdir(@tmpdir) if !File.exists?(@tmpdir)
  filename = File.expand_path(filename)
  raise "File does not exist: #{filename}" if !File.exists?(filename)
  filetime = File.mtime(filename)
  cachename = "#{@tmpdir}/#{filename.gsub("/", "_").gsub(".", "_")}.cache"
  cachetime = File.mtime(cachename) if File.exists?(cachename)
  
  begin
    if !File.exists?(cachename) or filetime > cachetime
      Knj::Eruby::Handler.load_file(filename, {:cachename => cachename})
      cachetime = File.mtime(cachename)
      reload_cache = true
    elsif !@cache.key?(cachename)
      reload_cache = true
    end
    
    case @cache_mode
      when :compile_knj
        @compiler.eval_file(:filepath => cachename, :fileident => filename)
      when :code_eval
        @cache[cachename] = File.read(cachename) if reload_cache
        eval(@cache[cachename], nil, filename)
      when :inseq
        if reload_cache or @cache[cachename][:time] < cachetime
          @cache[cachename] = {
            :inseq => RubyVM::InstructionSequence.compile(File.read(cachename), filename, nil, 1),
            :time => Time.now
          }
        end
        
        @cache[cachename][:inseq].eval
      else
        loaded_content = Knj::Eruby::Handler.load_file(filename, {:cachename => cachename})
        print loaded_content.evaluate
    end
  rescue SystemExit
    #do nothing.
  rescue Exception => e
    @error = true
    self.handle_error(e)
  end
end

#load_filename(filename, args = {}) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/knj/eruby.rb', line 176

def load_filename(filename, args = {})
  begin
    if !args[:custom_io]
      tmp_out = StringIO.new
      $stdout = tmp_out
    end
    
    self.import(filename)
    
    if @connects["exit"]
      @connects["exit"].each do |block|
        block.call
      end
    end
    
    self.printcont(tmp_out, args)
  rescue SystemExit => e
    self.printcont(tmp_out, args)
  rescue Exception => e
    self.handle_error(e)
    self.printcont(tmp_out, args)
  end
end

#load_return(filename, args = {}) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/knj/eruby.rb', line 162

def load_return(filename, args = {})
  if !args[:io]
    retio = StringIO.new
    args[:io] = retio
  end
  
  self.load_filename(filename, args)
  
  if !args[:custom_io]
    retio.rewind
    return retio.read
  end
end


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/knj/eruby.rb', line 95

def print_headers(args = {})
  header_str = ""
  
  @headers.each do |header|
    header_str << "#{header[0]}: #{header[1]}\n"
  end
  
  @cookies.each do |cookie|
    header_str << "Set-Cookie: #{Knj::Web.cookie_str(cookie)}\n"
  end
  
  header_str << "\n"
  self.reset_headers if @fcgi
  return header_str
end

#printcont(tmp_out, args = {}) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/knj/eruby.rb', line 141

def printcont(tmp_out, args = {})
  if @fcgi
    @fcgi.print self.print_headers
    tmp_out.rewind
    @fcgi.print tmp_out.read.to_s
  else
    if args[:io] and !args[:custom_io]
      old_out = $stdout
      $stdout = args[:io]
    elsif !args[:custom_io]
      $stdout = STDOUT
    end
    
    if !args[:custom_io]
      print self.print_headers if !args.key?(:with_headers) or args[:with_headers]
      tmp_out.rewind
      print tmp_out.read
    end
  end
end

#reset_connectsObject



119
120
121
# File 'lib/knj/eruby.rb', line 119

def reset_connects
  @connects = {}
end

#reset_headersObject



123
124
125
126
# File 'lib/knj/eruby.rb', line 123

def reset_headers
  @headers = []
  @cookies = []
end