ramaze 2008.06 → 2008.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +6 -6
- data/Rakefile +33 -3
- data/bin/ramaze +18 -0
- data/doc/CHANGELOG +960 -0
- data/doc/LEGAL +5 -1
- data/doc/meta/announcement.txt +20 -36
- data/doc/tutorial/todolist.html +421 -313
- data/doc/tutorial/todolist.mkd +33 -16
- data/examples/app/blog/spec/blog.rb +3 -3
- data/examples/app/rapaste/controller/paste.rb +8 -1
- data/examples/app/rapaste/model/paste.rb +3 -0
- data/examples/app/rapaste/spec/rapaste.rb +3 -1
- data/examples/app/rapaste/start.rb +3 -2
- data/examples/app/sourceview/public/sourceview.js +2 -2
- data/examples/app/todolist/spec/todolist.rb +6 -6
- data/examples/app/todolist/template/index.xhtml +1 -1
- data/examples/app/whywiki/spec/whywiki.rb +2 -2
- data/examples/app/wikore/spec/wikore.rb +2 -2
- data/examples/app/wikore/src/model.rb +4 -3
- data/examples/app/wiktacular/spec/wiktacular.rb +7 -7
- data/examples/basic/simple.rb +2 -2
- data/examples/helpers/paginate.rb +71 -0
- data/examples/misc/simple_auth.rb +20 -8
- data/lib/proto/controller/init.rb +10 -0
- data/lib/proto/controller/main.rb +1 -3
- data/lib/proto/model/init.rb +4 -0
- data/lib/proto/public/dispatch.fcgi +1 -1
- data/lib/proto/spec/main.rb +2 -1
- data/lib/proto/start.rb +3 -3
- data/lib/proto/start.ru +1 -1
- data/lib/proto/view/error.xhtml +4 -4
- data/lib/ramaze.rb +8 -3
- data/lib/ramaze/action.rb +6 -6
- data/lib/ramaze/adapter.rb +1 -6
- data/lib/ramaze/adapter/base.rb +30 -27
- data/lib/ramaze/adapter/cgi.rb +1 -0
- data/lib/ramaze/cache.rb +1 -3
- data/lib/ramaze/cache/memcached.rb +3 -5
- data/lib/ramaze/contrib/auto_params.rb +2 -2
- data/lib/ramaze/contrib/auto_params/get_args.rb +2 -1
- data/lib/ramaze/contrib/gems.rb +17 -18
- data/lib/ramaze/contrib/gzip_filter.rb +22 -9
- data/lib/ramaze/contrib/maruku_uv.rb +59 -0
- data/lib/ramaze/contrib/profiling.rb +1 -1
- data/lib/ramaze/contrib/rest.rb +16 -13
- data/lib/ramaze/contrib/sequel/create_join.rb +25 -0
- data/lib/ramaze/contrib/sequel/form_field.rb +129 -0
- data/lib/ramaze/contrib/sequel/image.rb +198 -0
- data/lib/ramaze/contrib/sequel/relation.rb +82 -0
- data/lib/ramaze/controller.rb +33 -34
- data/lib/ramaze/controller/resolve.rb +29 -9
- data/lib/ramaze/current.rb +60 -20
- data/lib/ramaze/current/request.rb +8 -7
- data/lib/ramaze/current/response.rb +15 -3
- data/lib/ramaze/current/session/flash.rb +8 -0
- data/lib/ramaze/dispatcher.rb +17 -9
- data/lib/ramaze/dispatcher/action.rb +4 -5
- data/lib/ramaze/dispatcher/directory.rb +1 -1
- data/lib/ramaze/dispatcher/error.rb +4 -4
- data/lib/ramaze/dispatcher/file.rb +4 -4
- data/lib/ramaze/gestalt.rb +15 -20
- data/lib/ramaze/helper/cgi.rb +7 -15
- data/lib/ramaze/helper/formatting.rb +41 -1
- data/lib/ramaze/helper/httpdigest.rb +20 -7
- data/lib/ramaze/helper/link.rb +4 -6
- data/lib/ramaze/helper/paginate.rb +233 -0
- data/lib/ramaze/helper/redirect.rb +1 -1
- data/lib/ramaze/helper/rest.rb +1 -1
- data/lib/ramaze/helper/thread.rb +17 -0
- data/lib/ramaze/helper/ultraviolet.rb +44 -0
- data/lib/ramaze/helper/user.rb +4 -9
- data/lib/ramaze/log.rb +2 -2
- data/lib/ramaze/log/analogger.rb +21 -23
- data/lib/ramaze/log/growl.rb +21 -23
- data/lib/ramaze/log/hub.rb +1 -1
- data/lib/ramaze/log/informer.rb +97 -99
- data/lib/ramaze/log/knotify.rb +14 -16
- data/lib/ramaze/log/logger.rb +11 -13
- data/lib/ramaze/log/logging.rb +61 -63
- data/lib/ramaze/log/rotatinginformer.rb +168 -0
- data/lib/ramaze/log/syslog.rb +41 -31
- data/lib/ramaze/log/xosd.rb +70 -72
- data/lib/ramaze/option.rb +9 -6
- data/lib/ramaze/option/holder.rb +5 -27
- data/lib/ramaze/reloader.rb +186 -0
- data/lib/ramaze/setup.rb +1 -1
- data/lib/ramaze/snippets.rb +13 -0
- data/lib/ramaze/snippets/array/put_within.rb +31 -24
- data/lib/ramaze/snippets/binding/locals.rb +23 -11
- data/lib/ramaze/snippets/dictionary.rb +2 -2
- data/lib/ramaze/snippets/fiber.rb +63 -0
- data/lib/ramaze/snippets/kernel/constant.rb +36 -21
- data/lib/ramaze/snippets/kernel/pretty_inspect.rb +12 -6
- data/lib/ramaze/snippets/numeric/filesize_format.rb +24 -17
- data/lib/ramaze/snippets/numeric/time.rb +63 -0
- data/lib/ramaze/snippets/object/__dir__.rb +29 -0
- data/lib/ramaze/snippets/object/acquire.rb +40 -0
- data/lib/ramaze/snippets/object/instance_variable_defined.rb +16 -5
- data/lib/ramaze/snippets/object/pretty.rb +14 -4
- data/lib/ramaze/snippets/object/scope.rb +14 -7
- data/lib/ramaze/snippets/ordered_set.rb +25 -14
- data/lib/ramaze/snippets/proc/locals.rb +17 -9
- data/lib/ramaze/snippets/ramaze/deprecated.rb +13 -0
- data/lib/ramaze/snippets/ramaze/fiber.rb +24 -0
- data/lib/ramaze/snippets/ramaze/state.rb +86 -0
- data/lib/ramaze/snippets/ramaze/struct.rb +45 -0
- data/lib/ramaze/snippets/string/camel_case.rb +13 -8
- data/lib/ramaze/snippets/string/color.rb +24 -20
- data/lib/ramaze/snippets/string/each.rb +14 -3
- data/lib/ramaze/snippets/string/end_with.rb +20 -0
- data/lib/ramaze/snippets/string/esc.rb +26 -21
- data/lib/ramaze/snippets/string/ord.rb +12 -6
- data/lib/ramaze/snippets/string/snake_case.rb +13 -7
- data/lib/ramaze/snippets/string/start_with.rb +16 -5
- data/lib/ramaze/snippets/string/unindent.rb +23 -15
- data/lib/ramaze/snippets/thread/into.rb +3 -3
- data/lib/ramaze/spec/helper/bacon.rb +5 -5
- data/lib/ramaze/spec/helper/mock_http.rb +1 -1
- data/lib/ramaze/spec/helper/pretty_output.rb +2 -2
- data/lib/ramaze/spec/helper/snippets.rb +8 -0
- data/lib/ramaze/template.rb +4 -1
- data/lib/ramaze/template/ezamar/textpow.syntax +34 -0
- data/lib/ramaze/template/maruku.rb +34 -0
- data/lib/ramaze/template/tagz.rb +2 -2
- data/lib/ramaze/template/xslt.rb +2 -2
- data/lib/ramaze/tool/create.rb +27 -53
- data/lib/ramaze/tool/localize.rb +8 -4
- data/lib/ramaze/tool/mime.rb +11 -1
- data/lib/ramaze/tool/project_creator.rb +110 -0
- data/lib/ramaze/trinity.rb +4 -1
- data/lib/ramaze/version.rb +1 -1
- data/lib/vendor/bacon.rb +323 -0
- data/rake_tasks/gem.rake +10 -1
- data/rake_tasks/maintenance.rake +40 -2
- data/rake_tasks/metric.rake +24 -0
- data/rake_tasks/release.rake +17 -4
- data/rake_tasks/spec.rake +1 -2
- data/ramaze.gemspec +549 -495
- data/spec/contrib/auto_params.rb +3 -3
- data/spec/contrib/profiling.rb +2 -2
- data/spec/examples/simple_auth.rb +2 -2
- data/spec/examples/templates/template_haml.rb +0 -2
- data/spec/ramaze/action/file_cache.rb +22 -0
- data/spec/ramaze/adapter.rb +2 -2
- data/spec/ramaze/controller/actionless_templates.rb +1 -1
- data/spec/ramaze/controller/subclass.rb +15 -0
- data/spec/ramaze/controller/template_resolving.rb +1 -1
- data/spec/ramaze/controller/view/bar.xhtml +1 -0
- data/spec/ramaze/controller/view/base/another.xhtml +1 -0
- data/spec/ramaze/current/session.rb +1 -1
- data/spec/ramaze/dispatcher/file.rb +2 -2
- data/spec/ramaze/helper/aspect.rb +26 -17
- data/spec/ramaze/helper/formatting.rb +13 -0
- data/spec/ramaze/log/informer.rb +10 -10
- data/spec/ramaze/log/syslog.rb +67 -4
- data/spec/ramaze/rewrite.rb +1 -1
- data/spec/ramaze/route.rb +1 -1
- data/spec/ramaze/struct.rb +47 -0
- data/spec/ramaze/template/markaby.rb +1 -1
- data/spec/ramaze/template/tagz.rb +1 -1
- data/spec/snippets/binding/locals.rb +9 -0
- data/spec/snippets/numeric/time.rb +12 -0
- data/spec/snippets/{kernel → object}/__dir__.rb +0 -0
- data/spec/snippets/{kernel → object}/acquire.rb +0 -0
- metadata +90 -81
- data/cache.yaml +0 -7
- data/examples/app/rammit/spec/rammit.rb +0 -31
- data/examples/app/rammit/src/controller/main.rb +0 -3
- data/examples/app/rammit/src/controller/page.rb +0 -16
- data/examples/app/rammit/src/model.rb +0 -33
- data/examples/app/rammit/start.rb +0 -8
- data/examples/app/rammit/template/index.xhtml +0 -14
- data/examples/app/rammit/template/page/view.xhtml +0 -4
- data/lib/ramaze/snippets/kernel/__dir__.rb +0 -23
- data/lib/ramaze/snippets/kernel/acquire.rb +0 -34
- data/lib/ramaze/snippets/object/thread_accessor.rb +0 -5
- data/lib/ramaze/snippets/ramaze/thread_accessor.rb +0 -58
- data/lib/ramaze/snippets/struct/fill.rb +0 -23
- data/lib/ramaze/snippets/struct/values_at.rb +0 -39
- data/lib/ramaze/snippets/symbol/to_proc.rb +0 -24
- data/lib/ramaze/sourcereload.rb +0 -176
- data/spec/snippets/struct/fill.rb +0 -26
- data/spec/snippets/struct/values_at.rb +0 -52
- data/spec/snippets/symbol/to_proc.rb +0 -13
data/lib/ramaze/option/holder.rb
CHANGED
@@ -95,16 +95,6 @@ module Ramaze
|
|
95
95
|
].find{|path| File.directory?(path) } || @view_root
|
96
96
|
end
|
97
97
|
|
98
|
-
def template_root=(tr)
|
99
|
-
Ramaze::deprecated "Global.template_root=", "Global.view_root="
|
100
|
-
self.view_root = tr
|
101
|
-
end
|
102
|
-
|
103
|
-
def template_root
|
104
|
-
Ramaze::deprecated "Global.template_root", "Global.view_root"
|
105
|
-
self.view_root
|
106
|
-
end
|
107
|
-
|
108
98
|
def adapter
|
109
99
|
find_from_aliases(@adapter, :adapter_aliases, Ramaze::Adapter, "ramaze/adapter")
|
110
100
|
end
|
@@ -114,17 +104,7 @@ module Ramaze
|
|
114
104
|
end
|
115
105
|
|
116
106
|
def sourcereload=(interval)
|
117
|
-
|
118
|
-
if interval.is_a?(Numeric)
|
119
|
-
@sourcereload = interval
|
120
|
-
Ramaze::SourceReload.restart
|
121
|
-
else
|
122
|
-
Log.warn("sourcereload= %p not Numeric, ignoring." % interval)
|
123
|
-
end
|
124
|
-
else
|
125
|
-
@sourcereload = interval
|
126
|
-
Ramaze::SourceReload.shutdown
|
127
|
-
end
|
107
|
+
Ramaze::Reloader::OPTIONS[:cooldown] = interval
|
128
108
|
end
|
129
109
|
|
130
110
|
private
|
@@ -133,17 +113,15 @@ module Ramaze
|
|
133
113
|
case name
|
134
114
|
when String, Symbol
|
135
115
|
name = name.to_s
|
136
|
-
|
137
|
-
find_require(name, mod, path)
|
116
|
+
class_name = self[alias_key][name] || name
|
117
|
+
find_require(name, class_name, mod, path)
|
138
118
|
else
|
139
119
|
name
|
140
120
|
end
|
141
121
|
end
|
142
122
|
|
143
|
-
def find_require(name, mod, path)
|
144
|
-
|
145
|
-
file_path = File.join(path, class_name.downcase)
|
146
|
-
|
123
|
+
def find_require(name, class_name, mod, path)
|
124
|
+
file_path = File.join(path, name)
|
147
125
|
require(file_path) unless mod.const_defined?(class_name)
|
148
126
|
|
149
127
|
mod.const_get(class_name)
|
@@ -0,0 +1,186 @@
|
|
1
|
+
# Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
3
|
+
|
4
|
+
module Ramaze
|
5
|
+
|
6
|
+
# High performant source reloader
|
7
|
+
#
|
8
|
+
# This class acts as Rack middleware.
|
9
|
+
#
|
10
|
+
# It does not depend on Ramaze itself, but you might have to adjust the
|
11
|
+
# Reloader::Hooks module or include your own module to override the hooks.
|
12
|
+
# You also might have to set the Log constant.
|
13
|
+
#
|
14
|
+
# What makes it especially suited for use in a production environment is that
|
15
|
+
# any file will only be checked once and there will only be made one system
|
16
|
+
# call stat(2).
|
17
|
+
#
|
18
|
+
# Please note that this will not reload files in the background, it does so
|
19
|
+
# only when actively called
|
20
|
+
# In case of Ramaze it is performing a check/reload cycle at the start of
|
21
|
+
# every request, but also respects a cool down time, during which nothing will
|
22
|
+
# be done.
|
23
|
+
#
|
24
|
+
# After every reload the OPTIONS hash will be checked for changed options and
|
25
|
+
# assigned to the instance, so you may change options during the lifetime of
|
26
|
+
# your application.
|
27
|
+
#
|
28
|
+
# A number of hooks will be executed during the reload cycle, see
|
29
|
+
# Ramaze::ReloaderHooks for more information.
|
30
|
+
|
31
|
+
class Reloader
|
32
|
+
OPTIONS = {
|
33
|
+
# At most check every n seconds
|
34
|
+
# nil/false will never trigger the reload cycle
|
35
|
+
# 0 will cycle on every call
|
36
|
+
:cooldown => 2,
|
37
|
+
|
38
|
+
# Compiled files cannot be reloaded during runtime
|
39
|
+
:ignore => /\.so$/,
|
40
|
+
|
41
|
+
# Run cycle in a Thread.exclusive, by default no threads are used.
|
42
|
+
:thread => false,
|
43
|
+
|
44
|
+
# If you assign a block here it will be instance_evaled instead of
|
45
|
+
# calling cycle. This allows you to use for example EventMachine for
|
46
|
+
# well performing asynchronous cycling.
|
47
|
+
:control => nil, # lambda{ cycle },
|
48
|
+
}
|
49
|
+
|
50
|
+
def initialize(app)
|
51
|
+
@app = app
|
52
|
+
@last = Time.now
|
53
|
+
@mtimes = {}
|
54
|
+
@cache = {}
|
55
|
+
options_reload
|
56
|
+
end
|
57
|
+
|
58
|
+
def options_reload
|
59
|
+
@cooldown, @ignore, @control, @thread =
|
60
|
+
OPTIONS.values_at(:cooldown, :ignore, :control, :thread)
|
61
|
+
end
|
62
|
+
|
63
|
+
def call(env)
|
64
|
+
options_reload
|
65
|
+
|
66
|
+
if @cooldown and Time.now > @last + @cooldown
|
67
|
+
if @control
|
68
|
+
instance_eval(&@control)
|
69
|
+
elsif @thread
|
70
|
+
Thread.exclusive{ cycle }
|
71
|
+
else
|
72
|
+
cycle
|
73
|
+
end
|
74
|
+
|
75
|
+
@last = Time.now
|
76
|
+
end
|
77
|
+
|
78
|
+
@app.call(env)
|
79
|
+
end
|
80
|
+
|
81
|
+
def cycle
|
82
|
+
before_cycle
|
83
|
+
|
84
|
+
rotation do |file, stat|
|
85
|
+
if mtime = stat.mtime
|
86
|
+
if mtime > (@mtimes[file] ||= mtime)
|
87
|
+
safe_load(file)
|
88
|
+
@mtimes[file] = mtime
|
89
|
+
end
|
90
|
+
else
|
91
|
+
@cache.delete(file)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
after_cycle
|
96
|
+
end
|
97
|
+
|
98
|
+
# A safe Kernel::load, issuing the hooks depending on the results
|
99
|
+
def safe_load(file)
|
100
|
+
before_safe_load(file)
|
101
|
+
load(file)
|
102
|
+
after_safe_load_succeed(file)
|
103
|
+
rescue Object => ex
|
104
|
+
Log.error(ex)
|
105
|
+
after_safe_load_failed(file, ex)
|
106
|
+
end
|
107
|
+
|
108
|
+
def rotation
|
109
|
+
files = [$0, __FILE__, *$LOADED_FEATURES].uniq
|
110
|
+
paths = ['./', *$LOAD_PATH].uniq
|
111
|
+
|
112
|
+
files.each do |file|
|
113
|
+
next if file =~ @ignore
|
114
|
+
path, stat = figure_path(file, paths)
|
115
|
+
|
116
|
+
if path and stat
|
117
|
+
@cache[file] = path
|
118
|
+
yield(path, stat)
|
119
|
+
else
|
120
|
+
# Quite harmless, we just couldn't figure out path for #{file}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def figure_path(file, paths)
|
126
|
+
if cached = @cache[file]
|
127
|
+
stat = File.stat(cached)
|
128
|
+
return cached, stat if stat.file?
|
129
|
+
elsif Pathname.new(file).absolute?
|
130
|
+
stat = File.stat(file)
|
131
|
+
return file, stat if stat.file? # do directories really end up in $" ?
|
132
|
+
end
|
133
|
+
|
134
|
+
paths.each do |possible_path|
|
135
|
+
path = File.join(possible_path, file)
|
136
|
+
|
137
|
+
begin
|
138
|
+
stat = File.stat(path)
|
139
|
+
return path, stat if stat.file?
|
140
|
+
rescue Errno::ENOENT, Errno::ENOTDIR
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
return nil
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
# Holds hooks that are called before and after #cycle and #safe_load
|
149
|
+
module Hooks
|
150
|
+
# Overwrite to add actions before the reload rotation is started.
|
151
|
+
def before_cycle
|
152
|
+
end
|
153
|
+
|
154
|
+
# Overwrite to add actions after the reload rotation has ended.
|
155
|
+
def after_cycle
|
156
|
+
end
|
157
|
+
|
158
|
+
# Overwrite to add actions before a file is Kernel::load-ed
|
159
|
+
def before_safe_load(file)
|
160
|
+
Log.debug("reload #{file}")
|
161
|
+
end
|
162
|
+
|
163
|
+
# Overwrite to add actions after a file is Kernel::load-ed successfully,
|
164
|
+
# by default we clean the Cache for compiled templates and resolved actions.
|
165
|
+
def after_safe_load_succeed(file)
|
166
|
+
Ramaze::Cache.compiled.clear
|
167
|
+
Ramaze::Cache.resolved.clear
|
168
|
+
Ramaze::Cache.action_methods.clear
|
169
|
+
after_safe_load(file)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Overwrite to add custom hook in addition to default Cache cleaning
|
173
|
+
def after_safe_load(file)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Overwrite to add actions after a file is Kernel::load-ed unsuccessfully,
|
177
|
+
# by default we output an error-message with the exception.
|
178
|
+
def after_safe_load_failed(file, error)
|
179
|
+
Log.error(error)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
include Hooks
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|
data/lib/ramaze/setup.rb
CHANGED
data/lib/ramaze/snippets.rb
CHANGED
@@ -7,3 +7,16 @@ glob = File.join(dir, '**', '*.rb')
|
|
7
7
|
Dir[glob].each do |snippet|
|
8
8
|
require(snippet)
|
9
9
|
end
|
10
|
+
|
11
|
+
Ramaze::CoreExtensions.constants.each do |const|
|
12
|
+
ext = Ramaze::CoreExtensions.const_get(const)
|
13
|
+
into = Module.const_get(const)
|
14
|
+
|
15
|
+
collisions = ext.instance_methods & into.instance_methods
|
16
|
+
|
17
|
+
if collisions.empty?
|
18
|
+
into.__send__(:include, ext)
|
19
|
+
else
|
20
|
+
warn "Won't include %p with %p, %p exists" % [into, ext, collisions]
|
21
|
+
end
|
22
|
+
end
|
@@ -1,37 +1,44 @@
|
|
1
1
|
# Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
|
2
2
|
# All files in this distribution are subject to the terms of the Ruby license.
|
3
3
|
|
4
|
-
|
4
|
+
module Ramaze
|
5
|
+
module CoreExtensions
|
5
6
|
|
6
|
-
|
7
|
-
# a.put_within(4, :after => 2, :before => 3)
|
8
|
-
# a # => [1, 2, 4, 3]
|
7
|
+
# Extensions for Array
|
9
8
|
|
10
|
-
|
11
|
-
pre, post = constrain.values_at(:after, :before)
|
9
|
+
module Array
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
# a = [1, 2, 3]
|
12
|
+
# a.put_within(4, :after => 2, :before => 3)
|
13
|
+
# a # => [1, 2, 4, 3]
|
16
14
|
|
17
|
-
|
18
|
-
|
15
|
+
def put_within(object, constrain)
|
16
|
+
pre, post = constrain.values_at(:after, :before)
|
19
17
|
|
20
|
-
|
21
|
-
# a.put_after(2, 4)
|
22
|
-
# a # => [1, 2, 4, 3]
|
18
|
+
return put_after(pre, object) if rindex(post) - index(pre) == 1
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
raise ArgumentError, "Too many elements within constrain"
|
21
|
+
end
|
22
|
+
|
23
|
+
# a = [1, 2, 3]
|
24
|
+
# a.put_after(2, 4)
|
25
|
+
# a # => [1, 2, 4, 3]
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
# a # => [1, 4, 2, 3]
|
27
|
+
def put_after(element, object)
|
28
|
+
return self[index(element) + 1, 0] = object if include?(element)
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
raise ArgumentError, "The given element doesn't exist"
|
31
|
+
end
|
32
|
+
|
33
|
+
# a = [1, 2, 3]
|
34
|
+
# a.put_before(2, 4)
|
35
|
+
# a # => [1, 4, 2, 3]
|
36
|
+
|
37
|
+
def put_before(element, object)
|
38
|
+
return self[rindex(element), 0] = object if include?(element)
|
39
|
+
|
40
|
+
raise ArgumentError, "The given element doesn't exist"
|
41
|
+
end
|
42
|
+
end
|
36
43
|
end
|
37
44
|
end
|
@@ -1,13 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def locals
|
8
|
-
Kernel::eval '
|
9
|
-
local_variables.inject({}){|h,v| h.update v => eval(v)}
|
10
|
-
', self
|
11
|
-
end
|
1
|
+
module Ramaze
|
2
|
+
module CoreExtensions
|
3
|
+
|
4
|
+
# Extensions for Binding
|
5
|
+
|
6
|
+
module Binding
|
12
7
|
|
8
|
+
# Returns a hash of localvar/localvar-values from binding, useful for
|
9
|
+
# template engines that do not accept bindings and force passing locals
|
10
|
+
# via hash
|
11
|
+
#
|
12
|
+
# Usage:
|
13
|
+
# x = 42; p binding.locals #=> {'x'=> 42}
|
14
|
+
|
15
|
+
def locals
|
16
|
+
::Kernel::eval '
|
17
|
+
local_variables.inject({}){|h,v|
|
18
|
+
k = v.to_s
|
19
|
+
h.merge!(k => eval(k))
|
20
|
+
}', self
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
13
25
|
end
|
@@ -362,7 +362,7 @@ module Ramaze
|
|
362
362
|
reorder
|
363
363
|
self
|
364
364
|
end
|
365
|
-
alias
|
365
|
+
alias merge! update
|
366
366
|
|
367
367
|
def merge( hsh2 )
|
368
368
|
self.dup.update(hsh2)
|
@@ -390,7 +390,7 @@ module Ramaze
|
|
390
390
|
def length
|
391
391
|
@order.length
|
392
392
|
end
|
393
|
-
alias
|
393
|
+
alias size length
|
394
394
|
|
395
395
|
def empty?
|
396
396
|
@hash.empty?
|
@@ -0,0 +1,63 @@
|
|
1
|
+
unless defined? Fiber
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
class FiberError < StandardError; end
|
5
|
+
|
6
|
+
class Fiber
|
7
|
+
def initialize
|
8
|
+
raise ArgumentError, 'new Fiber requires a block' unless block_given?
|
9
|
+
|
10
|
+
@yield = Queue.new
|
11
|
+
@resume = Queue.new
|
12
|
+
|
13
|
+
@thread = Thread.new{ @yield.push [*yield(*wait)] }
|
14
|
+
@thread.abort_on_exception = true
|
15
|
+
@thread[:fiber] = self
|
16
|
+
end
|
17
|
+
attr_reader :yield, :thread
|
18
|
+
|
19
|
+
def resume *args
|
20
|
+
raise FiberError, 'dead fiber called' unless @thread.alive?
|
21
|
+
@resume.push(args)
|
22
|
+
result = @yield.pop
|
23
|
+
result.size > 1 ? result : result.first
|
24
|
+
end
|
25
|
+
|
26
|
+
def wait
|
27
|
+
@resume.pop
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.yield *args
|
31
|
+
raise FiberError, "can't yield from root fiber" unless fiber = Thread.current[:fiber]
|
32
|
+
fiber.yield.push(args)
|
33
|
+
result = fiber.wait
|
34
|
+
result.size > 1 ? result : result.first
|
35
|
+
end
|
36
|
+
|
37
|
+
def inspect
|
38
|
+
"#<#{self.class}:0x#{self.object_id.to_s(16)}>"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if __FILE__ == $0
|
44
|
+
f = Fiber.new{ puts 'hi'; p Fiber.yield(1); puts 'bye'; :done }
|
45
|
+
p f.resume
|
46
|
+
p f.resume(2)
|
47
|
+
end
|
48
|
+
|
49
|
+
__END__
|
50
|
+
|
51
|
+
$ ruby fbr.rb
|
52
|
+
hi
|
53
|
+
1
|
54
|
+
2
|
55
|
+
bye
|
56
|
+
:done
|
57
|
+
|
58
|
+
$ ruby1.9 fbr.rb
|
59
|
+
hi
|
60
|
+
1
|
61
|
+
2
|
62
|
+
bye
|
63
|
+
:done
|