merb 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require 'fileutils'
7
7
  include FileUtils
8
8
 
9
9
  NAME = "merb"
10
- VERS = "0.0.2"
10
+ VERS = "0.0.3"
11
11
  CLEAN.include ['**/.*.sw?', '*.gem', '.config']
12
12
  RDOC_OPTS = ['--quiet', '--title', "Merb Documentation",
13
13
  "--opname", "index.html",
@@ -26,7 +26,7 @@ Rake::RDocTask.new do |rdoc|
26
26
  rdoc.options += RDOC_OPTS
27
27
  rdoc.main = "README"
28
28
  rdoc.title = "Merb Documentation"
29
- rdoc.rdoc_files.add ['README', 'LICENSE', 'lib/*.rb', 'server.rb']
29
+ rdoc.rdoc_files.add ['README', 'LICENSE', 'lib/*.rb']
30
30
  end
31
31
 
32
32
  spec = Gem::Specification.new do |s|
@@ -47,7 +47,7 @@ spec = Gem::Specification.new do |s|
47
47
  s.add_dependency('mongrel')
48
48
  s.required_ruby_version = '>= 1.8.4'
49
49
 
50
- s.files = %w(LICENSE README Rakefile server.rb) + Dir.glob("{app,bin,doc,test,lib,examples}/**/*")
50
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{app,bin,doc,test,lib,examples}/**/*")
51
51
 
52
52
  s.require_path = "lib"
53
53
  s.bindir = "bin"
@@ -3,8 +3,8 @@ class Posts < Merb::Controller
3
3
  template_dir :posts
4
4
 
5
5
  def new(args={})
6
- unless @params.to_s.empty?
7
- @post = Post.create( :title => @params[:title], :body => @params[:body])
6
+ unless params.to_s.empty?
7
+ @post = Post.create( :title => params[:title], :body => params[:body])
8
8
  render 'show'
9
9
  else
10
10
  render
@@ -12,7 +12,7 @@ class Posts < Merb::Controller
12
12
  end
13
13
 
14
14
  def show(args={})
15
- @post = Post.find @params[:id]
15
+ @post = Post.find args[:id]
16
16
  render
17
17
  end
18
18
 
@@ -2,13 +2,13 @@
2
2
  class Test < Merb::Controller
3
3
  template_dir :test
4
4
 
5
- def hello(args)
5
+ def hello(args={})
6
6
  # Assign the parameter to an instance variable
7
7
  @name = args[:id]
8
8
  render
9
9
  end
10
10
 
11
- def foo(args)
11
+ def foo(args={})
12
12
 
13
13
  @args = args
14
14
  render
@@ -1,16 +1,16 @@
1
1
  class Upload < Merb::Controller
2
2
  template_dir :upload
3
3
 
4
- def start(*args)
4
+ def start(args={})
5
5
  # Assign the parameter to an instance variable
6
6
  @args = args
7
7
  render
8
8
  end
9
9
 
10
- def upload(*args)
11
- puts @params[:file].inspect
10
+ def upload(args={})
11
+ puts params[:file].inspect
12
12
 
13
- FileUtils.mv @params[:file][:tempfile].path, ::Merb::Server.config[:merb_root]+"/public/files/#{@params[:file][:filename]}"
13
+ FileUtils.mv params[:file][:tempfile].path, ::Merb::Server.config[:merb_root]+"/public/files/#{params[:file][:filename]}"
14
14
 
15
15
  render
16
16
  end
@@ -3,7 +3,7 @@
3
3
  <title>New Post</title>
4
4
  </head>
5
5
  <body>
6
- <p><%= @params.inspect%></p>
6
+ <p><%= params.inspect%></p>
7
7
 
8
8
  <% @posts.each do |p| %>
9
9
  <h2><%= p.title %></h2>
@@ -3,7 +3,7 @@
3
3
  <title>New Post</title>
4
4
  </head>
5
5
  <body>
6
- <p><%= @params.inspect%></p>
6
+ <p><%= params.inspect%></p>
7
7
 
8
8
  <h2><%= @post.title %></h2>
9
9
  <p><%= @post.body %></p>
@@ -3,7 +3,7 @@
3
3
  <title>Hello, <%= @name %></title>
4
4
  </head>
5
5
  <body>
6
- <h1><%= @params.inspect %></h1>
6
+ <h1><%= params.inspect %></h1>
7
7
  <% 5.times do %>
8
8
  <h1>Hello, <%= @name %>!</h1>
9
9
  <% end %>
@@ -1,4 +1,4 @@
1
1
  <h2>File uploaded successfully</h2>
2
2
 
3
- <p>params for @params[:file].inspect</p>
4
- <%=@params[:file].inspect %>
3
+ <p>params for params[:file].inspect</p>
4
+ <%=params[:file].inspect %>
@@ -1,10 +1,19 @@
1
- puts "Compiling routes: \n"
1
+ # Merb::RouteMatcher is the request routing mapper for the merb framework.
2
+ # You can define placeholder parts of the url with the :smbol notation.
3
+ # so r.add '/foo/:bar/baz/:id', :class => 'Bar', :method => 'foo'
4
+ # will match against a request to /foo/123/baz/456. It will then
5
+ # use the class Bar as your merb controller and call the foo method on it.
6
+ # the foo method will recieve a hash with {:bar => '123', :id => '456'}
7
+ # as the content. So the :placeholders sections of your routes become
8
+ # a hash of arguments to your controller methods. These two methods map
9
+ # the default /controller/action and /controller/action/id urls you will
10
+ # use so you will want these two by default, in this order:
11
+ # r.add '/:class/:method/:id', {}
12
+ # r.add '/:class/:method', {}
2
13
 
14
+ puts "Compiling routes: \n"
3
15
  Merb::RouteMatcher.prepare do |r|
4
16
  r.add '/foo/:bar/baz/:id', :class => 'Test', :method => 'foo'
5
- r.add '/hey/:there/you/:guys', :class => 'Test', :method => 'hello'
6
- r.add '/upload/start', :class => 'Upload', :method => 'start'
7
- r.add '/posts/:method', :class => 'Posts'
8
17
  r.add '/:class/:method/:id', {}
9
18
  r.add '/:class/:method', {}
10
19
  end
@@ -1,7 +1,14 @@
1
1
  module Merb
2
2
 
3
+ # controller class for the merb pocket-framework. All of your
4
+ # controllers will inherit from Merb::Controller. This superclass
5
+ # takes care of parsing the incoming headers and body into params
6
+ # and cookies and headers. If the request is a file upload it will
7
+ # stream it into a tempfile and pass in the filename and tempfile object
8
+ # to your controller via params. It also parses the ?query=string and
9
+ # puts that into params as well.
3
10
  class Controller
4
- attr_accessor :status, :headers
11
+ attr_accessor :status
5
12
  # Stolen from Camping without a twinge of remorse ;)
6
13
  def initialize(req, env, method=(env['REQUEST_METHOD']||"GET")) #:nodoc:
7
14
  env = MerbHash[env.to_hash]
@@ -50,6 +57,18 @@ module Merb
50
57
  @cookies, @params = @k.dup, qs.dup
51
58
  end
52
59
 
60
+ def params
61
+ @params
62
+ end
63
+
64
+ def cookies
65
+ @cookies
66
+ end
67
+
68
+ def headers
69
+ @headers
70
+ end
71
+
53
72
  def query_parse(qs, d = '&;')
54
73
  m = proc {|_,o,n|o.update(n,&m)rescue([*o]<<n)}
55
74
  (qs||'').split(/[#{d}] */n).inject(MerbHash[]) { |h,p|
@@ -63,7 +63,7 @@ class Merb::Server
63
63
 
64
64
 
65
65
  h = Mongrel::HttpServer.new((@@merb_opts[:host]||"0.0.0.0"), (@@merb_opts[:port]||4000), (@@merb_opts[:numprocs]||40))
66
- h.register("/", MerbHandler.new)
66
+ h.register("/", MerbHandler.new(@@merb_opts[:merb_root]+'/public'))
67
67
  h.register("/favicon.ico", Mongrel::Error404Handler.new(""))
68
68
  h.run.join
69
69
 
@@ -1,64 +1,109 @@
1
1
  class MerbHandler < Mongrel::HttpHandler
2
+ @@file_only_methods = ["GET","HEAD"]
2
3
 
4
+ # take the name of a directory and use that as the doc root or public
5
+ # directory of your site. This is set to the root of your merb app + '/public'
6
+ # by default. See merb_daemon.rb if you want to change this.
7
+ def initialize(dir, opts = {})
8
+ @files = Mongrel::DirHandler.new(dir,false)
9
+ end
10
+
11
+ # process incoming http requests and do a number of things
12
+ # 1. check for rails style cached pages. add .html to the
13
+ # url and see if there is a static file in public that matches.
14
+ # serve that file directly without invoking Merb and be done with it.
15
+ # 2. Serve static asset and html files directly from public/ if
16
+ # they exist and fall back to Merb otherwise
17
+ # 3. If none of the above apply, we take apart the request url
18
+ # and feed it into Merb::RouteMatcher to let it decide which
19
+ # controller and method will serve the request.
20
+ # 4. after the controller has done its thing, we check for the
21
+ # X-SENDFILE header. if you set this header to the path to a file
22
+ # in your controller then mongrel will serve the file directly
23
+ # and your controller can go on processing other requests.
3
24
  def process(request, response)
25
+
4
26
  if response.socket.closed?
5
27
  return
6
28
  end
7
29
 
8
- begin
9
- controller, method, args = handle(request)
10
- output = if (controller && controller.kind_of?(Merb::Controller))
11
- if method
12
- ( args ? controller.send( method, args ) : controller.send(method) )
30
+ # Rails style page caching. Check the public dir first for
31
+ # .html pages and serve directly. Otherwise fall back to Merb
32
+ # routing and request dispatching.
33
+ path_info = request.params[Mongrel::Const::PATH_INFO]
34
+ page_cached = path_info + ".html"
35
+ get_or_head = @@file_only_methods.include? request.params[Mongrel::Const::REQUEST_METHOD]
36
+
37
+ if get_or_head and @files.can_serve(path_info)
38
+ # File exists as-is so serve it up
39
+ @files.process(request,response)
40
+ elsif get_or_head and @files.can_serve(page_cached)
41
+ # Possible cached page, serve it up
42
+ request.params[Mongrel::Const::PATH_INFO] = page_cached
43
+ @files.process(request,response)
44
+ else
45
+ begin
46
+ controller, method, args = handle(request)
47
+ output = if (controller && controller.kind_of?(Merb::Controller))
48
+ if method
49
+ ( args ? controller.send( method, args ) : controller.send(method) )
50
+ else
51
+ controller.to_s
52
+ end
13
53
  else
14
- controller.to_s
54
+ nil
55
+ end
56
+ rescue Exception => e
57
+ response.start(500) do |head,out|
58
+ head["Content-Type"] = "text/html"
59
+ out <<"<html><h2>Merb Error!</h2><pre>#{ e.message } - (#{ e.class })" <<
60
+ "\n" << "#{(e.backtrace or []).join('\n')}</pre></html>"
15
61
  end
16
- else
17
- nil
18
- end
19
- rescue Exception => e
20
- response.start(500) do |head,out|
21
- head["Content-Type"] = "text/html"
22
- out <<"<html><h2>Merb Error!</h2><pre>#{ e.message } - (#{ e.class })" <<
23
- "\n" << "#{(e.backtrace or []).join('\n')}</pre></html>"
62
+ return
24
63
  end
25
- return
26
- end
27
-
28
- unless output
29
- response.start(404) do |head,out|
30
- head["Content-Type"] = "text/html"
31
- out << "<html><body>Error: no merb controller found for this url.</body></html>"
64
+
65
+ unless output
66
+ response.start(404) do |head,out|
67
+ head["Content-Type"] = "text/html"
68
+ out << "<html><body>Error: no merb controller found for this url.</body></html>"
69
+ end
70
+ return
71
+ end
72
+
73
+ sendfile, clength = nil
74
+ response.status = controller.status
75
+
76
+ # check for the X-SENDFILE heaqder from your Merb::Controller
77
+ # and serve the file directly instead of buffering.
78
+ controller.headers.each do |k, v|
79
+ if k =~ /^X-SENDFILE$/i
80
+ sendfile = v
81
+ elsif k =~ /^CONTENT-LENGTH$/i
82
+ clength = v.to_i
83
+ else
84
+ [*v].each do |vi|
85
+ response.header[k] = vi
86
+ end
87
+ end
32
88
  end
33
- return
34
- end
35
-
36
- sendfile, clength = nil
37
- response.status = controller.status
38
- controller.headers.each do |k, v|
39
- if k =~ /^X-SENDFILE$/i
40
- sendfile = v
41
- elsif k =~ /^CONTENT-LENGTH$/i
42
- clength = v.to_i
89
+
90
+ if sendfile
91
+ # send X-SENDFILE header to mongrel
92
+ response.send_status(File.size(sendfile))
93
+ response.send_header
94
+ response.send_file(sendfile)
43
95
  else
44
- [*v].each do |vi|
45
- response.header[k] = vi
46
- end
96
+ # render response from successful controller
97
+ response.send_status(output.length)
98
+ response.send_header
99
+ response.write(output)
47
100
  end
48
101
  end
49
-
50
- if sendfile
51
- response.send_status(File.size(sendfile))
52
- response.send_header
53
- response.send_file(sendfile)
54
- else
55
- response.send_status(output.length)
56
- response.send_header
57
- response.write(output)
58
- end
59
-
60
102
  end
61
103
 
104
+ # This is where we grab the incoming request PATH_INFO
105
+ # and use that in the merb routematcher to determine
106
+ # which controller and method to run.
62
107
  def handle(request)
63
108
  path = request.params["PATH_INFO"].sub(/\/+/, '/')
64
109
  path = path[0..-2] if (path[-1] == ?/)
@@ -72,6 +117,10 @@ class MerbHandler < Mongrel::HttpHandler
72
117
  end
73
118
  end
74
119
 
120
+ # take a controller class name string and reload or require
121
+ # the right controller file then upcase the first letter and
122
+ # trun it into a new object p[assing in the request and response.
123
+ # this is where your Merb::Controller is instantiated.
75
124
  def instantiate_controller(controller_name, req, env)
76
125
  if !File.exist?(Merb::Server.config[:merb_root]+"/app/controllers/#{controller_name}.rb")
77
126
  return Object.const_get(:Noroutefound).new(req, env)
@@ -1,5 +1,30 @@
1
1
  module Merb
2
2
 
3
+ # Merb::RouteMatcher is the request routing mapper for the merb framework.
4
+ # You can define placeholder parts of the url with the :smbol notation.
5
+ # so r.add '/foo/:bar/baz/:id', :class => 'Bar', :method => 'foo'
6
+ # will match against a request to /foo/123/baz/456. It will then
7
+ # use the class Bar as your merb controller and call the foo method on it.
8
+ # the foo method will recieve a hash with {:bar => '123', :id => '456'}
9
+ # as the content. So the :placeholders sections of your routes become
10
+ # a hash of arguments to your controller methods. These two methods map
11
+ # the default /controller/action and /controller/action/id urls you will
12
+ # use so you will want these two by default, in this order:
13
+ # r.add '/:class/:method/:id', {}
14
+ # r.add '/:class/:method', {}
15
+ #
16
+ # This is what a route prepare definition looks like. I have added
17
+ # code that will spit out the compiled routing lambda so you can see
18
+ # what is generated:
19
+ #
20
+ # puts "Compiling routes: \n"
21
+ # Merb::RouteMatcher.prepare do |r|
22
+ # r.add '/foo/:bar/baz/:id', :class => 'Test', :method => 'foo'
23
+ # r.add '/:class/:method/:id', {}
24
+ # r.add '/:class/:method', {}
25
+ # end
26
+ # m = Merb::RouteMatcher.new
27
+ # puts m.compiled_statement
3
28
  class RouteMatcher
4
29
 
5
30
  attr_accessor :sections
@@ -55,33 +80,3 @@ module Merb
55
80
  end
56
81
 
57
82
  end
58
-
59
- =begin
60
- if __FILE__ == $0
61
- Merb::RouteMatcher.prepare do |r|
62
- r.add '/foo/:bar/baz/:id', :class => 'Test', :method => 'foo'
63
- r.add '/hey/:there/you/:guys', :class => 'Test', :method => 'hello'
64
- r.add '/these/:routes/are/:sweet', :class => 'Upload', :method => 'start'
65
- r.add '/h/:a/b/:c/d/:f/g/:id', :class => 'Test'
66
- r.add '/:class/:method/:id', {}
67
- r.add '/:class/:method', {}
68
- end
69
-
70
- routes = Merb::RouteMatcher.new
71
- puts routes.compiled_statement
72
- p routes.route_request( "/foo/234/baz/dsdsd")
73
- routes = Merb::RouteMatcher.new
74
- p routes.route_request( "/hey/jon/you/girls")
75
- routes = Merb::RouteMatcher.new
76
- p routes.route_request( "/upload/test/12")
77
- routes = Merb::RouteMatcher.new
78
- p routes.route_request( "/these/234/are/yup")
79
- routes = Merb::RouteMatcher.new
80
- p routes.route_request( '/h/12/b/red/d/blue/g/12')
81
- routes = Merb::RouteMatcher.new
82
- p routes.route_request( '/hdsfvsdfsdfdsf')
83
-
84
- p routes.routes
85
-
86
- end
87
- =end
data/lib/merb.rb CHANGED
@@ -6,7 +6,7 @@ require 'merb_config'
6
6
  require 'active_support'
7
7
 
8
8
  module Merb
9
- VERSION='0.0.2' unless defined?VERSION
9
+ VERSION='0.0.3' unless defined?VERSION
10
10
  end
11
11
 
12
12
  lib = File.join(File.dirname(__FILE__), 'merb')
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: merb
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.2
7
- date: 2006-10-16 00:00:00 -07:00
6
+ version: 0.0.3
7
+ date: 2006-10-17 00:00:00 -07:00
8
8
  summary: Merb == Mongrel + Erb. Pocket rocket web framework.
9
9
  require_paths:
10
10
  - lib
@@ -32,26 +32,7 @@ files:
32
32
  - LICENSE
33
33
  - README
34
34
  - Rakefile
35
- - server.rb
36
35
  - bin/merb
37
- - doc/rdoc
38
- - doc/rdoc/classes
39
- - doc/rdoc/created.rid
40
- - doc/rdoc/files
41
- - doc/rdoc/fr_class_index.html
42
- - doc/rdoc/fr_file_index.html
43
- - doc/rdoc/fr_method_index.html
44
- - doc/rdoc/index.html
45
- - doc/rdoc/rdoc-style.css
46
- - doc/rdoc/classes/Merb
47
- - doc/rdoc/classes/Merb.html
48
- - doc/rdoc/classes/Merb/Config.html
49
- - doc/rdoc/files/lib
50
- - doc/rdoc/files/LICENSE.html
51
- - doc/rdoc/files/README.html
52
- - doc/rdoc/files/server_rb.html
53
- - doc/rdoc/files/lib/merb_config_rb.html
54
- - doc/rdoc/files/lib/merb_rb.html
55
36
  - test/test_helper.rb
56
37
  - test/unit
57
38
  - test/unit/route_matcher_test.rb
@@ -1,159 +0,0 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
- <head>
8
- <title>Class: Merb::Config</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
- <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12
- <script type="text/javascript">
13
- // <![CDATA[
14
-
15
- function popupCode( url ) {
16
- window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
- }
18
-
19
- function toggleCode( id ) {
20
- if ( document.getElementById )
21
- elem = document.getElementById( id );
22
- else if ( document.all )
23
- elem = eval( "document.all." + id );
24
- else
25
- return false;
26
-
27
- elemStyle = elem.style;
28
-
29
- if ( elemStyle.display != "block" ) {
30
- elemStyle.display = "block"
31
- } else {
32
- elemStyle.display = "none"
33
- }
34
-
35
- return true;
36
- }
37
-
38
- // Make codeblocks hidden by default
39
- document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
-
41
- // ]]>
42
- </script>
43
-
44
- </head>
45
- <body>
46
-
47
-
48
-
49
- <div id="classHeader">
50
- <table class="header-table">
51
- <tr class="top-aligned-row">
52
- <td><strong>Class</strong></td>
53
- <td class="class-name-in-header">Merb::Config</td>
54
- </tr>
55
- <tr class="top-aligned-row">
56
- <td><strong>In:</strong></td>
57
- <td>
58
- <a href="../../files/lib/merb_config_rb.html">
59
- lib/merb_config.rb
60
- </a>
61
- <br />
62
- </td>
63
- </tr>
64
-
65
- <tr class="top-aligned-row">
66
- <td><strong>Parent:</strong></td>
67
- <td>
68
- Object
69
- </td>
70
- </tr>
71
- </table>
72
- </div>
73
- <!-- banner header -->
74
-
75
- <div id="bodyContent">
76
-
77
-
78
-
79
- <div id="contextContent">
80
-
81
-
82
-
83
- </div>
84
-
85
- <div id="method-list">
86
- <h3 class="section-bar">Methods</h3>
87
-
88
- <div class="name-list">
89
- <a href="#M000001">setup</a>&nbsp;&nbsp;
90
- </div>
91
- </div>
92
-
93
- </div>
94
-
95
-
96
- <!-- if includes -->
97
-
98
- <div id="section">
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
- <!-- if method_list -->
108
- <div id="methods">
109
- <h3 class="section-bar">Public Class methods</h3>
110
-
111
- <div id="method-M000001" class="method-detail">
112
- <a name="M000001"></a>
113
-
114
- <div class="method-heading">
115
- <a href="#M000001" class="method-signature">
116
- <span class="method-name">setup</span><span class="method-args">()</span>
117
- </a>
118
- </div>
119
-
120
- <div class="method-description">
121
- <p><a class="source-toggle" href="#"
122
- onclick="toggleCode('M000001-source');return false;">[Source]</a></p>
123
- <div class="method-source-code" id="M000001-source">
124
- <pre>
125
- <span class="ruby-comment cmt"># File lib/merb_config.rb, line 5</span>
126
- 5: <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">setup</span>
127
- 6: <span class="ruby-identifier">defaults</span> = {
128
- 7: <span class="ruby-identifier">:host</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">&quot;0.0.0.0&quot;</span>,
129
- 8: <span class="ruby-identifier">:port</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">&quot;4000&quot;</span>,
130
- 9: <span class="ruby-identifier">:allow_reloading</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-keyword kw">true</span>,
131
- 10: <span class="ruby-identifier">:merb_root</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-constant">Dir</span>.<span class="ruby-identifier">pwd</span>
132
- 11: }
133
- 12:
134
- 13: <span class="ruby-keyword kw">begin</span>
135
- 14: <span class="ruby-identifier">options</span> = <span class="ruby-identifier">defaults</span>.<span class="ruby-identifier">merge</span>(<span class="ruby-constant">YAML</span>.<span class="ruby-identifier">load</span>(<span class="ruby-constant">ERB</span>.<span class="ruby-identifier">new</span>(<span class="ruby-constant">IO</span>.<span class="ruby-identifier">read</span>(<span class="ruby-node">&quot;#{defaults[:merb_root]}/conf/merb.yml&quot;</span>)).<span class="ruby-identifier">result</span>))
136
- 15: <span class="ruby-keyword kw">rescue</span>
137
- 16: <span class="ruby-identifier">options</span> = <span class="ruby-identifier">defaults</span>
138
- 17: <span class="ruby-keyword kw">end</span>
139
- 18:
140
- 19: <span class="ruby-identifier">options</span>
141
- 20: <span class="ruby-keyword kw">end</span>
142
- </pre>
143
- </div>
144
- </div>
145
- </div>
146
-
147
-
148
- </div>
149
-
150
-
151
- </div>
152
-
153
-
154
- <div id="validator-badges">
155
- <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
156
- </div>
157
-
158
- </body>
159
- </html>