slippers 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/LICENSE +20 -0
  2. data/README +56 -0
  3. data/Rakefile +27 -0
  4. data/VERSION.yml +4 -0
  5. data/examples/blog/README +3 -0
  6. data/examples/blog/blog.db +0 -0
  7. data/examples/blog/controller/main.rb +30 -0
  8. data/examples/blog/model/entry.rb +31 -0
  9. data/examples/blog/public/styles/blog.css +132 -0
  10. data/examples/blog/spec/blog.rb +87 -0
  11. data/examples/blog/start.rb +7 -0
  12. data/examples/blog/view/edit.st +19 -0
  13. data/examples/blog/view/edit.xhtml +17 -0
  14. data/examples/blog/view/entry.st +12 -0
  15. data/examples/blog/view/index.st +4 -0
  16. data/examples/blog/view/index.xhtml +17 -0
  17. data/examples/blog/view/layout.st +11 -0
  18. data/examples/blog/view/layout.xhtml +11 -0
  19. data/examples/blog/view/new.st +16 -0
  20. data/examples/blog/view/new.xhtml +16 -0
  21. data/examples/forms/Rakefile +22 -0
  22. data/examples/forms/controller/init.rb +12 -0
  23. data/examples/forms/controller/main.rb +20 -0
  24. data/examples/forms/controller/registration.rb +24 -0
  25. data/examples/forms/forms.db +0 -0
  26. data/examples/forms/model/core_extensions/string_extensions.rb +5 -0
  27. data/examples/forms/model/field.rb +33 -0
  28. data/examples/forms/model/form.rb +33 -0
  29. data/examples/forms/model/init.rb +18 -0
  30. data/examples/forms/model/orm/registration.rb +12 -0
  31. data/examples/forms/model/registration_form_builder.rb +7 -0
  32. data/examples/forms/model/registration_repository.rb +39 -0
  33. data/examples/forms/model/registration_rules/incorrect_email_format.rb +11 -0
  34. data/examples/forms/model/registration_rules/number_field.rb +10 -0
  35. data/examples/forms/model/registration_rules/required_field.rb +9 -0
  36. data/examples/forms/model/registration_validator.rb +17 -0
  37. data/examples/forms/public/css/ramaze_error.css +90 -0
  38. data/examples/forms/public/dispatch.fcgi +11 -0
  39. data/examples/forms/public/favicon.ico +0 -0
  40. data/examples/forms/public/js/jquery.js +3549 -0
  41. data/examples/forms/public/ramaze.png +0 -0
  42. data/examples/forms/public/web-application.js +0 -0
  43. data/examples/forms/spec/form_spec.rb +16 -0
  44. data/examples/forms/spec/main.rb +25 -0
  45. data/examples/forms/spec/registration_controller_spec.rb +0 -0
  46. data/examples/forms/spec/registration_repository_spec.rb +38 -0
  47. data/examples/forms/spec/registration_validator_spec.rb +53 -0
  48. data/examples/forms/spec/spec_helper.rb +3 -0
  49. data/examples/forms/start.rb +12 -0
  50. data/examples/forms/start.ru +16 -0
  51. data/examples/forms/view/error.xhtml +64 -0
  52. data/examples/forms/view/index.xhtml +34 -0
  53. data/examples/forms/view/page.xhtml +27 -0
  54. data/examples/forms/view/registration/index.st +26 -0
  55. data/examples/main_controller.rb +40 -0
  56. data/examples/start.rb +7 -0
  57. data/examples/todolist/README +1 -0
  58. data/examples/todolist/controller/main.rb +71 -0
  59. data/examples/todolist/layout/page.rb +31 -0
  60. data/examples/todolist/model/tasks.rb +14 -0
  61. data/examples/todolist/public/favicon.ico +0 -0
  62. data/examples/todolist/public/js/jquery.js +1923 -0
  63. data/examples/todolist/public/ramaze.png +0 -0
  64. data/examples/todolist/start.rb +11 -0
  65. data/examples/todolist/todolist.db +11 -0
  66. data/examples/todolist/view/index.st +39 -0
  67. data/examples/todolist/view/index.xhtml +17 -0
  68. data/examples/todolist/view/new.st +41 -0
  69. data/examples/todolist/view/new.xhtml +7 -0
  70. data/examples/todolist/view/tasks.st +6 -0
  71. data/examples/todolist.db +5 -0
  72. data/examples/view/index.st +11 -0
  73. data/examples/view/person/age.st +1 -0
  74. data/examples/view/person/age_renderer.rb +6 -0
  75. data/examples/view/person/index.st +2 -0
  76. data/lib/engine/binding_wrapper.rb +10 -0
  77. data/lib/engine/engine.rb +28 -0
  78. data/lib/engine/file_template.rb +12 -0
  79. data/lib/engine/slippers.treetop +169 -0
  80. data/lib/engine/slippers_nodes.rb +119 -0
  81. data/lib/engine/template.rb +17 -0
  82. data/lib/engine/template_group.rb +40 -0
  83. data/lib/engine/template_group_directory.rb +57 -0
  84. data/lib/ramazeTemplates/0001-Adding-slippers-as-a-new-template.patch +138 -0
  85. data/lib/ramazeTemplates/0002-Fixing-problem-with-using-other-renderers.patch +27 -0
  86. data/lib/ramazeTemplates/slippers.rb +22 -0
  87. data/lib/slippers.rb +14 -0
  88. data/spec/binding_wrapper.rb +19 -0
  89. data/spec/engine.rb +89 -0
  90. data/spec/file_template.rb +9 -0
  91. data/spec/parse_attributes.rb +98 -0
  92. data/spec/parse_renderers.rb +35 -0
  93. data/spec/parse_templates.rb +73 -0
  94. data/spec/person_template.st +1 -0
  95. data/spec/spec_helper.rb +14 -0
  96. data/spec/template_group.rb +52 -0
  97. data/spec/template_group_directory.rb +43 -0
  98. data/spec/views/index.st +1 -0
  99. data/spec/views/money.rb +2 -0
  100. data/spec/views/person/age.st +1 -0
  101. data/spec/views/person/date_renderer.rb +5 -0
  102. data/spec/views/person/name.st +1 -0
  103. metadata +218 -0
Binary file
@@ -0,0 +1,11 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'rubygems'
5
+ require 'ramaze'
6
+
7
+ require 'controller/main'
8
+ #require 'layout/page'
9
+ require 'model/tasks'
10
+
11
+ Ramaze.start :port => 3000
@@ -0,0 +1,11 @@
1
+ ---
2
+ Watch the tv:
3
+ :done: false
4
+ Wash dishes:
5
+ :done: true
6
+ Clean the shower:
7
+ :done: false
8
+ Laundry:
9
+ :done: false
10
+ Vacuum the room:
11
+ :done: false
@@ -0,0 +1,39 @@
1
+ <html>
2
+ <head>
3
+ <title>TodoList</title>
4
+ <style>
5
+ table {
6
+ width: 100%;
7
+ }
8
+
9
+ tr {
10
+ background: #efe;
11
+ width: 100%;
12
+ }
13
+
14
+ tr:hover {
15
+ background: #dfd;
16
+ }
17
+
18
+ td.title {
19
+ font-weight: bold;
20
+ width: 60%;
21
+ }
22
+
23
+ td.status {
24
+ margin: 1em;
25
+ }
26
+
27
+ a {
28
+ color: #3a3;
29
+ }
30
+ </style>
31
+ </head>
32
+ <body>
33
+ <h1>$heading$</h1>
34
+ <a href="/new">New Task</a>
35
+ <table>
36
+ $tasks:tasks()$
37
+ </table>
38
+ </body>
39
+ </html>
@@ -0,0 +1,17 @@
1
+ <Page title="TodoList">
2
+ <a href="/new">New Task</a>
3
+ <?r if @tasks.empty? ?>
4
+ No Tasks
5
+ <?r else ?>
6
+ <table>
7
+ <?r @tasks.each do |title, status, toggle, delete| ?>
8
+ <tr>
9
+ <td class="title"> #{h title} </td>
10
+ <td class="status"> #{status} </td>
11
+ <td class="toggle"> #{toggle} </td>
12
+ <td class="delete"> #{delete} </td>
13
+ </tr>
14
+ <?r end ?>
15
+ </table>
16
+ <?r end ?>
17
+ </Page>
@@ -0,0 +1,41 @@
1
+ <html>
2
+ <head>
3
+ <title>TodoList</title>
4
+ <style>
5
+ table {
6
+ width: 100%;
7
+ }
8
+
9
+ tr {
10
+ background: #efe;
11
+ width: 100%;
12
+ }
13
+
14
+ tr:hover {
15
+ background: #dfd;
16
+ }
17
+
18
+ td.title {
19
+ font-weight: bold;
20
+ width: 60%;
21
+ }
22
+
23
+ td.status {
24
+ margin: 1em;
25
+ }
26
+
27
+ a {
28
+ color: #3a3;
29
+ }
30
+ </style>
31
+ </head>
32
+ <body>
33
+ <h1>New Task</h1>
34
+ <a href="/">Back to TodoList</a>
35
+ <form method="POST" action="create">
36
+ Task: <input type="text" name="title" /><br />
37
+ <input type="submit" />
38
+ </form>
39
+
40
+ </body>
41
+ </html>
@@ -0,0 +1,7 @@
1
+ <Page title="New Task">
2
+ <a href="/">Back to TodoList</a>
3
+ <form method="POST" action="create">
4
+ Task: <input type="text" name="title" /><br />
5
+ <input type="submit" />
6
+ </form>
7
+ </Page>
@@ -0,0 +1,6 @@
1
+ <tr>
2
+ <td class="title">$title$</td>
3
+ <td class="status">$status$</td>
4
+ <td class="status"><a href="/$toggle$/$resource$">$toggle$ tasks</a></td>
5
+ <td class="status"><a href="/delete/$resource$">delete</a></td>
6
+ </tr>
@@ -0,0 +1,5 @@
1
+ ---
2
+ Wash dishes:
3
+ :done: false
4
+ Laundry:
5
+ :done: false
@@ -0,0 +1,11 @@
1
+ <html>
2
+ <head>
3
+ <title>Slippers</title>
4
+ </head>
5
+ <body>
6
+ $person:person/index()$
7
+ <div>
8
+ This is authored by $author:author()$.
9
+ </div>
10
+ </body>
11
+ </html>
@@ -0,0 +1 @@
1
+ is $person/age_renderer()$ years old
@@ -0,0 +1,6 @@
1
+ class AgeRenderer
2
+ def render(date)
3
+ age = DateTime.now.year - date.year
4
+ age.to_s
5
+ end
6
+ end
@@ -0,0 +1,2 @@
1
+ <h3>Introducing....</h3>
2
+ <p>the faboulous <strong>$name$</strong> who $dob:person/age()$ is a $role$</p>
@@ -0,0 +1,10 @@
1
+ module Slippers
2
+ class BindingWrapper
3
+ def initialize(bindings)
4
+ @bindings = bindings
5
+ end
6
+ def [](method)
7
+ eval('@'+ method.to_s, @bindings)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ Treetop.load File.dirname(__FILE__) + '/slippers'
2
+
3
+ module Slippers
4
+ class Engine
5
+ DEFAULT_STRING = ''
6
+ def initialize(template, params={})
7
+ @main_template = Slippers::Template.new(template)
8
+ @template_group = params[:template_group]
9
+ end
10
+ attr_reader :main_template, :template_group
11
+
12
+ def render(object_to_render=nil)
13
+ parser = SlippersParser.new
14
+ parse_tree = parser.parse(@main_template.template)
15
+ return '' unless parse_tree
16
+ parse_tree.eval(object_to_render, @template_group)
17
+ end
18
+
19
+ def eql?(other)
20
+ @main_template.eql?(other.main_template) && @template_group.eql?(other.template_group)
21
+ end
22
+
23
+ def hash
24
+ @main_template.hash + @template_group.hash*23
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,12 @@
1
+ module Slippers
2
+ class FileTemplate < Template
3
+ def initialize(filename)
4
+ @filename = filename
5
+ end
6
+ attr_reader :filename
7
+ def template()
8
+ return @template if @template
9
+ @template = File.read(@filename)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,169 @@
1
+ grammar Slippers
2
+
3
+ rule expression
4
+ before:some_text expression_to_render space after:expression <ExpressionNode> / some_text
5
+ end
6
+
7
+ rule expression_to_render
8
+ conditional_template / templated_expression
9
+ end
10
+
11
+ rule templated_expression
12
+ delimiter foo delimiter <TemplatedExpressionNode>
13
+ end
14
+
15
+ rule foo
16
+ apply_attribute_to_template / template / expression_option / attribute
17
+ end
18
+
19
+ rule apply_attribute_to_template
20
+ attribute apply_op template <ApplyAttributeToTemplateNode>
21
+ end
22
+
23
+ rule template
24
+ known_template / anonymous_template
25
+ end
26
+
27
+ rule known_template
28
+ template_path brackets <TemplateNode>
29
+ end
30
+
31
+ rule anonymous_template
32
+ "{" anonymous_template_words "}" <AnonymousTemplateNode>
33
+ end
34
+
35
+ rule attribute
36
+ anything_except_keywords <AttributeToRenderNode>
37
+ end
38
+
39
+ rule expression_option
40
+ attribute:anything_except_keywords ';' space null_subtitute:('null="' nulls:anything_except_keywords '"')? (",")? space seperator_value:('seperator="' seps:anything_except_keywords '"' )? <AttributeWithExpressionOptionNode>
41
+ end
42
+
43
+ rule conditional_template
44
+ "$if(" if_clause:attribute ")$" if_expression:expression else_clause:('$else$' else_expression:expression)? '$end$' <ConditionalTemplateNode>
45
+
46
+ end
47
+
48
+ rule some_text
49
+ not_delimiter* {
50
+ def eval(*args)
51
+ to_s
52
+ end
53
+ def to_s
54
+ text_value
55
+ end
56
+ }
57
+ end
58
+
59
+ rule anonymous_template_words
60
+ not_curly* {
61
+ def to_s
62
+ text_value
63
+ end
64
+ }
65
+ end
66
+
67
+ rule template_path
68
+ anything_except_keywords {
69
+ def to_s
70
+ text_value
71
+ end
72
+ }
73
+ end
74
+
75
+ rule anything_except_keywords
76
+ not_keyword* {
77
+ def eval(*args)
78
+ to_s
79
+ end
80
+ def to_s
81
+ text_value
82
+ end
83
+ }
84
+ end
85
+
86
+ rule word_with_underscore
87
+ word ("_" word)*
88
+ end
89
+
90
+ rule word
91
+ [a-zA-Z]+ {
92
+ def to_s
93
+ text_value
94
+ end
95
+ }
96
+ end
97
+
98
+ rule space
99
+ ' '* {
100
+ def eval(object_to_render=nil, template_group=nil)
101
+ to_s
102
+ end
103
+ def to_s
104
+ text_value
105
+ end
106
+ }
107
+ end
108
+
109
+ rule apply_op
110
+ ':' {
111
+ def to_s
112
+ text_value
113
+ end
114
+ }
115
+ end
116
+
117
+ rule delimiter
118
+ '$' {
119
+ def to_s
120
+ text_value
121
+ end
122
+ }
123
+ end
124
+
125
+ rule brackets
126
+ '()' {
127
+ def to_s
128
+ text_value
129
+ end
130
+ }
131
+ end
132
+
133
+ rule escape
134
+ '\\'
135
+ end
136
+
137
+ rule not_delimiter
138
+ escape delimiter / !delimiter . {
139
+ def to_s
140
+ text_value
141
+ end
142
+ }
143
+ end
144
+
145
+ rule not_apply_op
146
+ !apply_op . {
147
+ def to_s
148
+ text_value
149
+ end
150
+ }
151
+ end
152
+
153
+ rule not_keyword
154
+ !(apply_op / delimiter / brackets / ';' / '"' / ")" / "if" / "else" / "end" ) . {
155
+ def to_s
156
+ text_value
157
+ end
158
+ }
159
+ end
160
+
161
+ rule not_curly
162
+ !("{" / "}") . {
163
+ def to_s
164
+ text_value
165
+ end
166
+ }
167
+ end
168
+
169
+ end
@@ -0,0 +1,119 @@
1
+ module Slippers
2
+ module AttributeToRenderNode
3
+
4
+ def eval(object_to_render, template_group)
5
+ [object_to_render].flatten.inject('') { |rendered, item| rendered + render(value_of(item), template_group) }
6
+ end
7
+
8
+ def value_of(item)
9
+ return '' if attribute == ''
10
+ return item.to_s if attribute == 'it'
11
+ return item[to_sym] if item.respond_to?('[]'.to_sym) && item[to_sym]
12
+ return item.send(attribute) if item.respond_to?(attribute)
13
+ Slippers::Engine::DEFAULT_STRING
14
+ end
15
+
16
+ def render(object_to_render, template_group)
17
+ substitue_null_values(object_to_render)
18
+ return template_group.render(object_to_render) if template_group && template_group.has_registered?(object_to_render.class)
19
+ return object_to_render.compact.join(seperator) if seperator && object_to_render.respond_to?('join')
20
+ object_to_render.to_s
21
+ end
22
+
23
+ def substitue_null_values(object_to_render)
24
+ return unless null_values && object_to_render.respond_to?('map!')
25
+ object_to_render.map!{|x| if x then x else null_values end }
26
+ end
27
+
28
+ def to_sym
29
+ attribute.to_sym
30
+ end
31
+
32
+ def null_values
33
+ end
34
+
35
+ def seperator
36
+ end
37
+
38
+ def attribute
39
+ text_value
40
+ end
41
+ end
42
+
43
+ class AttributeWithExpressionOptionNode < Treetop::Runtime::SyntaxNode
44
+ include AttributeToRenderNode
45
+ def seperator
46
+ seperator_value.seps.to_s if seperator_value.elements
47
+ end
48
+ def null_values
49
+ null_subtitute.nulls.to_s if null_subtitute.elements
50
+ end
51
+ end
52
+
53
+ class TemplateNode < Treetop::Runtime::SyntaxNode
54
+
55
+ def eval(object_to_render, template_group)
56
+ apply_attribute_to_subtemplate(object_to_render, template_group)
57
+ end
58
+
59
+ def apply_attribute_to_subtemplate(item, template_group)
60
+ return '' unless template_group
61
+ subtemplate = template_group.find(template_path.to_s)
62
+ return '' unless (subtemplate && subtemplate.respond_to?('render'))
63
+ subtemplate.render(item)
64
+ end
65
+ end
66
+
67
+ class AnonymousTemplateNode < Treetop::Runtime::SyntaxNode
68
+
69
+ def eval(object_to_render, template_group)
70
+ apply_attribute_to_subtemplate(object_to_render, template_group)
71
+ end
72
+
73
+ def apply_attribute_to_subtemplate(item, template_group)
74
+ SlippersParser.new.parse(anonymous_template_words.to_s).eval(item, template_group)
75
+ end
76
+ end
77
+
78
+ class ApplyAttributeToTemplateNode < Treetop::Runtime::SyntaxNode
79
+
80
+ def eval(object_to_render, template_group)
81
+ [object_to_render].flatten.inject('') { |rendered, item| rendered + find_attribute_and_render(item, template_group) }
82
+ end
83
+
84
+ def find_attribute_and_render(item, template_group)
85
+ object_to_render = attribute.value_of(item)
86
+ [object_to_render].flatten.inject('') { |rendered, i| rendered + template.apply_attribute_to_subtemplate(i, template_group).to_s }
87
+ end
88
+ end
89
+
90
+ class ConditionalTemplateNode < Treetop::Runtime::SyntaxNode
91
+
92
+ def eval(object_to_render, template_group)
93
+ attribute = if_clause.value_of(object_to_render)
94
+ if (attribute && attribute != Slippers::Engine::DEFAULT_STRING) then
95
+ if_expression.eval(object_to_render, template_group)
96
+ else
97
+ if else_clause.elements then else_clause.else_expression.eval(object_to_render, template_group) else Slippers::Engine::DEFAULT_STRING end
98
+ end
99
+ end
100
+
101
+
102
+ end
103
+
104
+ class TemplatedExpressionNode < Treetop::Runtime::SyntaxNode
105
+
106
+ def eval(object_to_render, template_group)
107
+ foo.eval(object_to_render, template_group)
108
+ end
109
+
110
+ end
111
+
112
+ class ExpressionNode < Treetop::Runtime::SyntaxNode
113
+
114
+ def eval(object_to_render, template_group=nil)
115
+ before.eval(object_to_render, template_group) + expression_to_render.eval(object_to_render, template_group) + space.eval + after.eval(object_to_render, template_group)
116
+ end
117
+
118
+ end
119
+ end
@@ -0,0 +1,17 @@
1
+ module Slippers
2
+ class Template
3
+ def initialize(template)
4
+ @template = template
5
+ end
6
+ attr_reader :template
7
+
8
+ def eql?(other)
9
+ template.eql?(other.template)
10
+ end
11
+
12
+ def hash
13
+ template.hash
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,40 @@
1
+ module Slippers
2
+ class TemplateGroup
3
+ def initialize(params={})
4
+ @templates = params[:templates]
5
+ @super_group = params[:super_group]
6
+ end
7
+
8
+ def find(subtemplate)
9
+ return nil unless @templates
10
+ return create_template(subtemplate.to_sym) if @templates.include?(subtemplate.to_sym)
11
+ find_in_super_group(subtemplate)
12
+ end
13
+
14
+ def has_registered?(class_name)
15
+ return false unless @templates
16
+ return true if @templates.include?(class_name)
17
+ return false unless @super_group
18
+ @super_group.has_registered?(class_name)
19
+ end
20
+
21
+ def render(item)
22
+ return '' unless @templates
23
+ return @templates[item.class].render(item) if has_registered?(item.class)
24
+ return '' unless @super_group
25
+ @super_group.render(item)
26
+ end
27
+
28
+ private
29
+ def find_in_super_group(subtemplate)
30
+ return nil unless @super_group
31
+ @super_group.find(subtemplate)
32
+ end
33
+
34
+ def create_template(subtemplate)
35
+ template = @templates[subtemplate]
36
+ return template unless template.is_a?(String)
37
+ Slippers::Engine.new(template)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,57 @@
1
+ module Slippers
2
+ class TemplateGroupDirectory < TemplateGroup
3
+ def initialize(directory_paths, params={})
4
+ @directory_paths = directory_paths
5
+ @super_group = params[:super_group]
6
+ end
7
+ attr_reader :directory_paths
8
+
9
+ def find(subtemplate)
10
+ file_name = @directory_paths.map { |directory_path| directory_path + '/' + subtemplate + '.st' }.find { |f| File.exist? f}
11
+ return Engine.new(FileTemplate.new(file_name).template, :template_group => self) if file_name
12
+ find_renderer_or_supergroup(subtemplate)
13
+ end
14
+
15
+ def has_registered?(class_name)
16
+ return false unless @super_group
17
+ @super_group.has_registered?(class_name)
18
+ end
19
+
20
+ def render(item)
21
+ return '' unless @super_group
22
+ @super_group.render(item)
23
+ end
24
+
25
+
26
+ def eql?(other)
27
+ return false unless other
28
+ directory_paths.eql?(other.directory_paths)
29
+ end
30
+ def hash
31
+ @directory_paths.hash
32
+ end
33
+
34
+ private
35
+ def find_renderer_or_supergroup(subtemplate)
36
+ file_name = @directory_paths.map { |directory_path| directory_path + '/' + subtemplate + '.rb' }.find { |f| File.exist? f}
37
+ return find_in_super_group(subtemplate) unless file_name
38
+
39
+ renderer_name = subtemplate.split('/')[-1]
40
+ load File.expand_path(file_name)
41
+ create_renderer renderer_name
42
+ end
43
+
44
+ def find_in_super_group(subtemplate)
45
+ return nil unless @super_group
46
+ @super_group.find(subtemplate)
47
+ end
48
+
49
+ def create_renderer(renderer_name)
50
+ camelCase = renderer_name.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
51
+ classes = camelCase.split('::')
52
+ classes.shift if classes.empty? or classes.first.empty?
53
+ const = classes.inject(Object){ |constant, class_name| constant.const_get(class_name) }
54
+ const.new
55
+ end
56
+ end
57
+ end