railties 3.0.0.beta4 → 3.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/CHANGELOG +24 -6
  2. data/README.rdoc +25 -0
  3. data/guides/assets/javascripts/code_highlighter.js +0 -0
  4. data/guides/assets/javascripts/guides.js +0 -0
  5. data/guides/assets/stylesheets/print.css +0 -0
  6. data/guides/assets/stylesheets/reset.css +0 -0
  7. data/guides/assets/stylesheets/style.css +0 -0
  8. data/guides/source/3_0_release_notes.textile +5 -3
  9. data/guides/source/action_controller_overview.textile +19 -0
  10. data/guides/source/active_record_basics.textile +27 -21
  11. data/guides/source/active_record_querying.textile +39 -37
  12. data/guides/source/{activerecord_validations_callbacks.textile → active_record_validations_callbacks.textile} +30 -29
  13. data/guides/source/active_support_core_extensions.textile +232 -107
  14. data/guides/source/api_documentation_guidelines.textile +187 -0
  15. data/guides/source/association_basics.textile +45 -1
  16. data/guides/source/configuring.textile +7 -7
  17. data/guides/source/contributing_to_rails.textile +42 -15
  18. data/guides/source/form_helpers.textile +1 -1
  19. data/guides/source/generators.textile +37 -37
  20. data/guides/source/getting_started.textile +11 -11
  21. data/guides/source/i18n.textile +1 -1
  22. data/guides/source/index.html.erb +14 -6
  23. data/guides/source/initialization.textile +130 -124
  24. data/guides/source/layout.html.erb +5 -2
  25. data/guides/source/layouts_and_rendering.textile +2 -2
  26. data/guides/source/migrations.textile +4 -3
  27. data/guides/source/plugins.textile +15 -15
  28. data/guides/source/rails_application_templates.textile +2 -2
  29. data/guides/source/routing.textile +83 -62
  30. data/guides/source/security.textile +2 -2
  31. data/guides/w3c_validator.rb +30 -6
  32. data/lib/rails.rb +3 -3
  33. data/lib/rails/application.rb +43 -19
  34. data/lib/rails/application/bootstrap.rb +2 -0
  35. data/lib/rails/application/configuration.rb +3 -3
  36. data/lib/rails/application/finisher.rb +6 -6
  37. data/lib/rails/cli.rb +1 -19
  38. data/lib/rails/commands.rb +5 -5
  39. data/lib/rails/commands/application.rb +1 -1
  40. data/lib/rails/commands/console.rb +1 -4
  41. data/lib/rails/commands/generate.rb +0 -0
  42. data/lib/rails/commands/plugin.rb +57 -52
  43. data/lib/rails/commands/runner.rb +2 -1
  44. data/lib/rails/commands/server.rb +6 -2
  45. data/lib/rails/configuration.rb +2 -3
  46. data/lib/rails/console/app.rb +0 -2
  47. data/lib/rails/engine.rb +14 -15
  48. data/lib/rails/engine/configuration.rb +5 -5
  49. data/lib/rails/generators.rb +2 -3
  50. data/lib/rails/generators/actions.rb +4 -4
  51. data/lib/rails/generators/base.rb +1 -1
  52. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +1 -6
  53. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb +4 -4
  54. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb +3 -3
  55. data/lib/rails/generators/erb/scaffold/templates/index.html.erb +7 -7
  56. data/lib/rails/generators/erb/scaffold/templates/new.html.erb +2 -2
  57. data/lib/rails/generators/erb/scaffold/templates/show.html.erb +3 -3
  58. data/lib/rails/generators/generated_attribute.rb +2 -1
  59. data/lib/rails/generators/named_base.rb +24 -0
  60. data/lib/rails/generators/rails/app/app_generator.rb +10 -9
  61. data/lib/rails/generators/rails/app/templates/Gemfile +4 -3
  62. data/lib/rails/generators/rails/app/templates/README +6 -31
  63. data/lib/rails/generators/rails/app/templates/Rakefile +1 -1
  64. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb +0 -1
  65. data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
  66. data/lib/rails/generators/rails/app/templates/config/application.rb +11 -11
  67. data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml +36 -24
  68. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +1 -1
  69. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -1
  70. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +3 -0
  71. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +3 -0
  72. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +3 -0
  73. data/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb +1 -1
  74. data/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt +2 -2
  75. data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +2 -2
  76. data/lib/rails/generators/rails/app/templates/config/routes.rb +1 -1
  77. data/lib/rails/generators/rails/app/templates/public/index.html +0 -17
  78. data/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js +2027 -900
  79. data/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +114 -57
  80. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +1 -1
  81. data/lib/rails/generators/rails/model/USAGE +1 -1
  82. data/lib/rails/generators/rails/resource/resource_generator.rb +4 -14
  83. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +0 -2
  84. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +28 -30
  85. data/lib/rails/generators/resource_helpers.rb +1 -1
  86. data/lib/rails/generators/test_case.rb +25 -11
  87. data/lib/rails/generators/test_unit/model/model_generator.rb +1 -1
  88. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +0 -1
  89. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +13 -15
  90. data/lib/rails/info.rb +1 -2
  91. data/lib/rails/info_routes.rb +1 -1
  92. data/lib/rails/initializable.rb +3 -16
  93. data/lib/rails/paths.rb +31 -36
  94. data/lib/rails/plugin.rb +10 -6
  95. data/lib/rails/rack/logger.rb +11 -13
  96. data/lib/rails/railtie.rb +14 -42
  97. data/lib/rails/ruby_version_check.rb +19 -5
  98. data/lib/rails/script_rails_loader.rb +29 -0
  99. data/lib/rails/tasks/annotations.rake +2 -2
  100. data/lib/rails/tasks/documentation.rake +47 -16
  101. data/lib/rails/tasks/framework.rake +9 -9
  102. data/lib/rails/tasks/middleware.rake +1 -1
  103. data/lib/rails/tasks/misc.rake +5 -5
  104. data/lib/rails/tasks/routes.rake +1 -1
  105. data/lib/rails/tasks/tmp.rake +5 -5
  106. data/lib/rails/test_unit/testing.rake +38 -14
  107. data/lib/rails/version.rb +1 -1
  108. metadata +29 -17
  109. data/README +0 -281
  110. data/lib/rails/application/routes_reloader.rb +0 -46
  111. data/lib/rails/log_subscriber.rb +0 -115
  112. data/lib/rails/log_subscriber/test_helper.rb +0 -97
  113. data/lib/rails/webrick_server.rb +0 -156
@@ -16,7 +16,7 @@ module TestUnit
16
16
 
17
17
  def create_fixture_file
18
18
  if options[:fixture] && options[:fixture_replacement].nil?
19
- template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml")
19
+ template 'fixtures.yml', File.join('test/fixtures', class_path, "#{plural_file_name}.yml")
20
20
  end
21
21
  end
22
22
  end
@@ -6,7 +6,6 @@ module TestUnit
6
6
  class ScaffoldGenerator < Base
7
7
  include Rails::Generators::ResourceHelpers
8
8
 
9
- class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
10
9
  check_class_collision :suffix => "ControllerTest"
11
10
 
12
11
  def create_test_files
@@ -2,50 +2,48 @@ require 'test_helper'
2
2
 
3
3
  class <%= controller_class_name %>ControllerTest < ActionController::TestCase
4
4
  setup do
5
- @<%= file_name %> = <%= table_name %>(:one)
5
+ @<%= singular_table_name %> = <%= table_name %>(:one)
6
6
  end
7
7
 
8
- <% unless options[:singleton] -%>
9
8
  test "should get index" do
10
9
  get :index
11
10
  assert_response :success
12
11
  assert_not_nil assigns(:<%= table_name %>)
13
12
  end
14
- <% end -%>
15
13
 
16
14
  test "should get new" do
17
15
  get :new
18
16
  assert_response :success
19
17
  end
20
18
 
21
- test "should create <%= file_name %>" do
19
+ test "should create <%= singular_table_name %>" do
22
20
  assert_difference('<%= class_name %>.count') do
23
- post :create, :<%= file_name %> => @<%= file_name %>.attributes
21
+ post :create, :<%= singular_table_name %> => @<%= singular_table_name %>.attributes
24
22
  end
25
23
 
26
- assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
24
+ assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
27
25
  end
28
26
 
29
- test "should show <%= file_name %>" do
30
- get :show, :id => @<%= file_name %>.to_param
27
+ test "should show <%= singular_table_name %>" do
28
+ get :show, :id => @<%= singular_table_name %>.to_param
31
29
  assert_response :success
32
30
  end
33
31
 
34
32
  test "should get edit" do
35
- get :edit, :id => @<%= file_name %>.to_param
33
+ get :edit, :id => @<%= singular_table_name %>.to_param
36
34
  assert_response :success
37
35
  end
38
36
 
39
- test "should update <%= file_name %>" do
40
- put :update, :id => @<%= file_name %>.to_param, :<%= file_name %> => @<%= file_name %>.attributes
41
- assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
37
+ test "should update <%= singular_table_name %>" do
38
+ put :update, :id => @<%= singular_table_name %>.to_param, :<%= singular_table_name %> => @<%= singular_table_name %>.attributes
39
+ assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
42
40
  end
43
41
 
44
- test "should destroy <%= file_name %>" do
42
+ test "should destroy <%= singular_table_name %>" do
45
43
  assert_difference('<%= class_name %>.count', -1) do
46
- delete :destroy, :id => @<%= file_name %>.to_param
44
+ delete :destroy, :id => @<%= singular_table_name %>.to_param
47
45
  end
48
46
 
49
- assert_redirected_to <%= table_name %>_path
47
+ assert_redirected_to <%= index_helper %>_path
50
48
  end
51
49
  end
@@ -1,4 +1,3 @@
1
- require "active_support/core_ext/object/misc"
2
1
  require "cgi"
3
2
  require "active_support/core_ext/cgi"
4
3
 
@@ -89,7 +88,7 @@ module Rails
89
88
  end
90
89
 
91
90
  property 'Middleware' do
92
- Rails.configuration.middleware.active.map(&:inspect)
91
+ Rails.configuration.middleware.map(&:inspect)
93
92
  end
94
93
 
95
94
  # The application's location on the filesystem.
@@ -1,3 +1,3 @@
1
- Rails.application.routes.draw do |map|
1
+ Rails.application.routes.draw do
2
2
  match '/rails/info/properties' => "rails/info#properties"
3
3
  end
@@ -39,11 +39,6 @@ module Rails
39
39
  select { |i| i.before == initializer.name || i.name == initializer.after }.each(&block)
40
40
  end
41
41
 
42
- def initialize(initializers = [])
43
- super(initializers)
44
- replace(tsort)
45
- end
46
-
47
42
  def +(other)
48
43
  Collection.new(to_a + other.to_a)
49
44
  end
@@ -51,7 +46,7 @@ module Rails
51
46
 
52
47
  def run_initializers(*args)
53
48
  return if instance_variable_defined?(:@ran)
54
- initializers.each do |initializer|
49
+ initializers.tsort.each do |initializer|
55
50
  initializer.run(*args)
56
51
  end
57
52
  @ran = true
@@ -63,7 +58,7 @@ module Rails
63
58
 
64
59
  module ClassMethods
65
60
  def initializers
66
- @initializers ||= []
61
+ @initializers ||= Collection.new
67
62
  end
68
63
 
69
64
  def initializers_chain
@@ -84,14 +79,6 @@ module Rails
84
79
  opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] }
85
80
  initializers << Initializer.new(name, nil, opts, &blk)
86
81
  end
87
-
88
- def run_initializers(*args)
89
- return if @ran
90
- initializers_chain.each do |initializer|
91
- instance_exec(*args, &initializer.block)
92
- end
93
- @ran = true
94
- end
95
82
  end
96
83
  end
97
- end
84
+ end
@@ -25,9 +25,7 @@ module Rails
25
25
 
26
26
  def initialize(path)
27
27
  raise if path.is_a?(Array)
28
-
29
28
  @children = {}
30
-
31
29
  @path = path
32
30
  @root = self
33
31
  @all_paths = []
@@ -38,14 +36,18 @@ module Rails
38
36
  @all_paths
39
37
  end
40
38
 
41
- def load_once
42
- filter_by(:load_once?)
39
+ def autoload_once
40
+ filter_by(:autoload_once?)
43
41
  end
44
42
 
45
43
  def eager_load
46
44
  filter_by(:eager_load?)
47
45
  end
48
46
 
47
+ def autoload_paths
48
+ filter_by(:autoload?)
49
+ end
50
+
49
51
  def load_paths
50
52
  filter_by(:load_path?)
51
53
  end
@@ -61,15 +63,17 @@ module Rails
61
63
  protected
62
64
 
63
65
  def filter_by(constraint)
64
- all_paths.map do |path|
66
+ all = []
67
+ all_paths.each do |path|
65
68
  if path.send(constraint)
66
69
  paths = path.paths
67
70
  paths -= path.children.values.map { |p| p.send(constraint) ? [] : p.paths }.flatten
68
- paths
69
- else
70
- []
71
+ all.concat(paths)
71
72
  end
72
- end.flatten.uniq.select { |p| File.exists?(p) }
73
+ end
74
+ all.uniq!
75
+ all.reject! { |p| !File.exists?(p) }
76
+ all
73
77
  end
74
78
  end
75
79
 
@@ -80,15 +84,16 @@ module Rails
80
84
  attr_accessor :glob
81
85
 
82
86
  def initialize(root, *paths)
83
- @options = paths.last.is_a?(::Hash) ? paths.pop : {}
87
+ options = paths.last.is_a?(::Hash) ? paths.pop : {}
84
88
  @children = {}
85
89
  @root = root
86
90
  @paths = paths.flatten
87
- @glob = @options.delete(:glob)
91
+ @glob = options[:glob]
88
92
 
89
- @load_once = @options[:load_once]
90
- @eager_load = @options[:eager_load]
91
- @load_path = @options[:load_path] || @eager_load || @load_once
93
+ autoload_once! if options[:autoload_once]
94
+ eager_load! if options[:eager_load]
95
+ autoload! if options[:autoload]
96
+ load_path! if options[:load_path]
92
97
 
93
98
  @root.all_paths << self
94
99
  end
@@ -111,30 +116,20 @@ module Rails
111
116
  @paths.concat paths
112
117
  end
113
118
 
114
- def load_once!
115
- @load_once = true
116
- @load_path = true
117
- end
118
-
119
- def load_once?
120
- @load_once
121
- end
122
-
123
- def eager_load!
124
- @eager_load = true
125
- @load_path = true
126
- end
127
-
128
- def eager_load?
129
- @eager_load
130
- end
119
+ %w(autoload_once eager_load autoload load_path).each do |m|
120
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
121
+ def #{m}!
122
+ @#{m} = true
123
+ end
131
124
 
132
- def load_path!
133
- @load_path = true
134
- end
125
+ def skip_#{m}!
126
+ @#{m} = false
127
+ end
135
128
 
136
- def load_path?
137
- @load_path
129
+ def #{m}?
130
+ @#{m}
131
+ end
132
+ RUBY
138
133
  end
139
134
 
140
135
  def paths
@@ -61,6 +61,16 @@ module Rails
61
61
  @config ||= Engine::Configuration.new
62
62
  end
63
63
 
64
+ initializer :handle_lib_autoload, :before => :set_load_path do |app|
65
+ paths = if app.config.reload_plugins
66
+ config.autoload_paths
67
+ else
68
+ config.autoload_once_paths
69
+ end
70
+
71
+ paths.concat config.paths.lib.to_a
72
+ end
73
+
64
74
  initializer :load_init_rb, :before => :load_config_initializers do |app|
65
75
  files = %w(rails/init.rb init.rb).map { |path| File.expand_path path, root }
66
76
  if initrb = files.find { |path| File.file? path }
@@ -77,11 +87,5 @@ module Rails
77
87
  raise "\"#{name}\" is a Railtie/Engine and cannot be installed as plugin"
78
88
  end
79
89
  end
80
-
81
- protected
82
-
83
- def reloadable?(app)
84
- app.config.reload_plugins
85
- end
86
90
  end
87
91
  end
@@ -1,10 +1,9 @@
1
- require 'rails/log_subscriber'
2
1
  require 'active_support/core_ext/time/conversions'
3
2
 
4
3
  module Rails
5
4
  module Rack
6
5
  # Log the request started and flush all loggers after it.
7
- class Logger < Rails::LogSubscriber
6
+ class Logger < ActiveSupport::LogSubscriber
8
7
  def initialize(app)
9
8
  @app = app
10
9
  end
@@ -16,20 +15,19 @@ module Rails
16
15
  after_dispatch(env)
17
16
  end
18
17
 
19
- protected
18
+ protected
20
19
 
21
- def before_dispatch(env)
22
- request = ActionDispatch::Request.new(env)
23
- path = request.fullpath
20
+ def before_dispatch(env)
21
+ request = ActionDispatch::Request.new(env)
22
+ path = request.fullpath
24
23
 
25
- info "\n\nStarted #{env["REQUEST_METHOD"]} \"#{path}\" " \
26
- "for #{request.ip} at #{Time.now.to_default_s}"
27
- end
28
-
29
- def after_dispatch(env)
30
- Rails::LogSubscriber.flush_all!
31
- end
24
+ info "\n\nStarted #{env["REQUEST_METHOD"]} \"#{path}\" " \
25
+ "for #{request.ip} at #{Time.now.to_default_s}"
26
+ end
32
27
 
28
+ def after_dispatch(env)
29
+ ActiveSupport::LogSubscriber.flush_all!
30
+ end
33
31
  end
34
32
  end
35
33
  end
@@ -10,7 +10,7 @@ module Rails
10
10
  # Every major component of Rails (Action Mailer, Action Controller,
11
11
  # Action View, Active Record and Active Resource) are all Railties, so each of
12
12
  # them is responsible to set their own initialization. This makes, for example,
13
- # Rails absent of any ActiveRecord hook, allowing any other ORM framework to hook in.
13
+ # Rails absent of any Active Record hook, allowing any other ORM framework to hook in.
14
14
  #
15
15
  # Developing a Rails extension does _not_ require any implementation of
16
16
  # Railtie, but if you need to interact with the Rails framework during
@@ -70,7 +70,7 @@ module Rails
70
70
  #
71
71
  # class MyRailtie < Rails::Railtie
72
72
  # initializer "my_railtie.configure_rails_initialization" do |app|
73
- # app.middlewares.use MyRailtie::Middleware
73
+ # app.middleware.use MyRailtie::Middleware
74
74
  # end
75
75
  # end
76
76
  #
@@ -114,36 +114,6 @@ module Rails
114
114
  # end
115
115
  # end
116
116
  #
117
- # == Adding your subscriber
118
- #
119
- # Since version 3.0, Rails ships with a notification system which is used for several
120
- # purposes, including logging. If you are sending notifications in your Railtie, you may
121
- # want to add a subscriber to consume such notifications for logging purposes.
122
- #
123
- # The subscriber is added under the railtie_name namespace and only consumes notifications
124
- # under the given namespace. For example, let's suppose your railtie is publishing the
125
- # following "something_expensive" instrumentation:
126
- #
127
- # ActiveSupport::Notifications.instrument "my_railtie.something_expensive" do
128
- # # something expensive
129
- # end
130
- #
131
- # You can log this instrumentation with your own Rails::Subscriber:
132
- #
133
- # class MyRailtie::Subscriber < Rails::Subscriber
134
- # def something_expensive(event)
135
- # info("Something expensive took %.1fms" % event.duration)
136
- # end
137
- # end
138
- #
139
- # By registering it:
140
- #
141
- # class MyRailtie < Railtie
142
- # subscriber :my_gem, MyRailtie::Subscriber.new
143
- # end
144
- #
145
- # Take a look in Rails::Subscriber docs for more information.
146
- #
147
117
  # == Application, Plugin and Engine
148
118
  #
149
119
  # A Rails::Engine is nothing more than a Railtie with some initializers already set.
@@ -176,8 +146,8 @@ module Rails
176
146
  ActiveSupport::Deprecation.warn "railtie_name is deprecated and has no effect", caller
177
147
  end
178
148
 
179
- def log_subscriber(name, log_subscriber)
180
- Rails::LogSubscriber.add(name, log_subscriber)
149
+ def log_subscriber(*)
150
+ ActiveSupport::Deprecation.warn "log_subscriber is deprecated and has no effect", caller
181
151
  end
182
152
 
183
153
  def rake_tasks(&blk)
@@ -186,6 +156,12 @@ module Rails
186
156
  @rake_tasks
187
157
  end
188
158
 
159
+ def console(&blk)
160
+ @load_console ||= []
161
+ @load_console << blk if blk
162
+ @load_console
163
+ end
164
+
189
165
  def generators(&blk)
190
166
  @generators ||= []
191
167
  @generators << blk if blk
@@ -200,20 +176,16 @@ module Rails
200
176
  def eager_load!
201
177
  end
202
178
 
203
- def rake_tasks
204
- self.class.rake_tasks
205
- end
206
-
207
- def generators
208
- self.class.generators
179
+ def load_console
180
+ self.class.console.each(&:call)
209
181
  end
210
182
 
211
183
  def load_tasks
212
- rake_tasks.each { |blk| blk.call }
184
+ self.class.rake_tasks.each(&:call)
213
185
  end
214
186
 
215
187
  def load_generators
216
- generators.each { |blk| blk.call }
188
+ self.class.generators.each(&:call)
217
189
  end
218
190
  end
219
191
  end
@@ -1,10 +1,24 @@
1
- min_release = "1.8.7"
2
- ruby_release = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE})"
3
- if ruby_release < min_release
1
+ if RUBY_VERSION < '1.8.7'
2
+ desc = defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})"
4
3
  abort <<-end_message
5
4
 
6
- Rails requires Ruby version #{min_release} or later.
7
- You're running #{ruby_release}; please upgrade to continue.
5
+ Rails 3 requires Ruby 1.8.7 or 1.9.2.
6
+
7
+ You're running
8
+ #{desc}
9
+
10
+ Please upgrade to continue.
11
+
12
+ end_message
13
+ elsif RUBY_VERSION > '1.9' and RUBY_VERSION < '1.9.2'
14
+ $stderr.puts <<-end_message
15
+
16
+ Rails 3 doesn't officially support Ruby 1.9.1 since recent stable
17
+ releases have segfaulted the test suite. Please upgrade to Ruby 1.9.2
18
+ before Rails 3 is released!
19
+
20
+ You're running
21
+ #{RUBY_DESCRIPTION}
8
22
 
9
23
  end_message
10
24
  end