thorero 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/History.txt +1 -0
  2. data/LICENSE +20 -0
  3. data/Manifest +45 -0
  4. data/Manifest.txt +29 -0
  5. data/README.txt +3 -0
  6. data/Rakefile +180 -0
  7. data/lib/extlib.rb +32 -0
  8. data/lib/extlib/assertions.rb +8 -0
  9. data/lib/extlib/blank.rb +42 -0
  10. data/lib/extlib/class.rb +175 -0
  11. data/lib/extlib/hash.rb +410 -0
  12. data/lib/extlib/hook.rb +366 -0
  13. data/lib/extlib/inflection.rb +141 -0
  14. data/lib/extlib/lazy_array.rb +106 -0
  15. data/lib/extlib/logger.rb +202 -0
  16. data/lib/extlib/mash.rb +143 -0
  17. data/lib/extlib/module.rb +37 -0
  18. data/lib/extlib/object.rb +165 -0
  19. data/lib/extlib/object_space.rb +13 -0
  20. data/lib/extlib/pathname.rb +5 -0
  21. data/lib/extlib/pooling.rb +233 -0
  22. data/lib/extlib/rubygems.rb +38 -0
  23. data/lib/extlib/simple_set.rb +39 -0
  24. data/lib/extlib/string.rb +132 -0
  25. data/lib/extlib/struct.rb +8 -0
  26. data/lib/extlib/tasks/release.rb +11 -0
  27. data/lib/extlib/time.rb +12 -0
  28. data/lib/extlib/version.rb +3 -0
  29. data/lib/extlib/virtual_file.rb +10 -0
  30. data/spec/blank_spec.rb +85 -0
  31. data/spec/hash_spec.rb +524 -0
  32. data/spec/hook_spec.rb +1198 -0
  33. data/spec/inflection_spec.rb +50 -0
  34. data/spec/lazy_array_spec.rb +896 -0
  35. data/spec/mash_spec.rb +244 -0
  36. data/spec/module_spec.rb +58 -0
  37. data/spec/object_space_spec.rb +9 -0
  38. data/spec/object_spec.rb +98 -0
  39. data/spec/pooling_spec.rb +486 -0
  40. data/spec/simple_set_spec.rb +26 -0
  41. data/spec/spec_helper.rb +8 -0
  42. data/spec/string_spec.rb +200 -0
  43. data/spec/struct_spec.rb +12 -0
  44. data/spec/time_spec.rb +16 -0
  45. data/spec/virtual_file_spec.rb +21 -0
  46. data/thorero.gemspec +147 -0
  47. metadata +146 -0
@@ -0,0 +1,141 @@
1
+ # The original of this file was copied for the ActiveSupport project which is
2
+ # part of the Ruby On Rails web-framework (http://rubyonrails.org)
3
+ #
4
+ # Methods have been modified or removed. English inflection is now provided via
5
+ # the english gem (http://english.rubyforge.org)
6
+ #
7
+ # sudo gem install english
8
+ #
9
+ gem 'english', '>=0.2.0'
10
+ require 'english/inflect'
11
+
12
+ English::Inflect.word 'postgres'
13
+
14
+ module Extlib
15
+ module Inflection
16
+ class << self
17
+ # Take an underscored name and make it into a camelized name
18
+ #
19
+ # @example
20
+ # "egg_and_hams".classify #=> "EggAndHam"
21
+ # "post".classify #=> "Post"
22
+ #
23
+ def classify(name)
24
+ camelize(singularize(name.to_s.sub(/.*\./, '')))
25
+ end
26
+
27
+ # By default, camelize converts strings to UpperCamelCase.
28
+ #
29
+ # camelize will also convert '/' to '::' which is useful for converting paths to namespaces
30
+ #
31
+ # @example
32
+ # "active_record".camelize #=> "ActiveRecord"
33
+ # "active_record/errors".camelize #=> "ActiveRecord::Errors"
34
+ #
35
+ def camelize(lower_case_and_underscored_word, *args)
36
+ lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
37
+ end
38
+
39
+
40
+ # The reverse of +camelize+. Makes an underscored form from the expression in the string.
41
+ #
42
+ # Changes '::' to '/' to convert namespaces to paths.
43
+ #
44
+ # @example
45
+ # "ActiveRecord".underscore #=> "active_record"
46
+ # "ActiveRecord::Errors".underscore #=> active_record/errors
47
+ #
48
+ def underscore(camel_cased_word)
49
+ camel_cased_word.to_s.gsub(/::/, '/').
50
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
51
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
52
+ tr("-", "_").
53
+ downcase
54
+ end
55
+
56
+ # Capitalizes the first word and turns underscores into spaces and strips _id.
57
+ # Like titleize, this is meant for creating pretty output.
58
+ #
59
+ # @example
60
+ # "employee_salary" #=> "Employee salary"
61
+ # "author_id" #=> "Author"
62
+ def humanize(lower_case_and_underscored_word)
63
+ lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
64
+ end
65
+
66
+ # Removes the module part from the expression in the string
67
+ #
68
+ # @example
69
+ # "ActiveRecord::CoreExtensions::String::Inflections".demodulize #=> "Inflections"
70
+ # "Inflections".demodulize #=> "Inflections"
71
+ def demodulize(class_name_in_module)
72
+ class_name_in_module.to_s.gsub(/^.*::/, '')
73
+ end
74
+
75
+ # Create the name of a table like Rails does for models to table names. This method
76
+ # uses the pluralize method on the last word in the string.
77
+ #
78
+ # @example
79
+ # "RawScaledScorer".tableize #=> "raw_scaled_scorers"
80
+ # "egg_and_ham".tableize #=> "egg_and_hams"
81
+ # "fancyCategory".tableize #=> "fancy_categories"
82
+ def tableize(class_name)
83
+ pluralize(underscore(class_name))
84
+ end
85
+
86
+ # Creates a foreign key name from a class name.
87
+ #
88
+ # @example
89
+ # "Message".foreign_key #=> "message_id"
90
+ # "Admin::Post".foreign_key #=> "post_id"
91
+ def foreign_key(class_name, key = "id")
92
+ underscore(demodulize(class_name.to_s)) << "_" << key.to_s
93
+ end
94
+
95
+ # Constantize tries to find a declared constant with the name specified
96
+ # in the string. It raises a NameError when the name is not in CamelCase
97
+ # or is not initialized.
98
+ #
99
+ # @example
100
+ # "Module".constantize #=> Module
101
+ # "Class".constantize #=> Class
102
+ def constantize(camel_cased_word)
103
+ unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
104
+ raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
105
+ end
106
+
107
+ Object.module_eval("::#{$1}", __FILE__, __LINE__)
108
+ end
109
+
110
+ # The reverse of pluralize, returns the singular form of a word in a string.
111
+ # Wraps the English gem
112
+ #
113
+ # @example
114
+ # "posts".singularize #=> "post"
115
+ # "octopi".singularize #=> "octopus"
116
+ # "sheep".singluarize #=> "sheep"
117
+ # "word".singluarize #=> "word"
118
+ # "the blue mailmen".singularize #=> "the blue mailman"
119
+ # "CamelOctopi".singularize #=> "CamelOctopus"
120
+ #
121
+ def singularize(word)
122
+ English::Inflect.singular(word)
123
+ end
124
+
125
+ # Returns the plural form of the word in the string.
126
+ #
127
+ # @example
128
+ # "post".pluralize #=> "posts"
129
+ # "octopus".pluralize #=> "octopi"
130
+ # "sheep".pluralize #=> "sheep"
131
+ # "words".pluralize #=> "words"
132
+ # "the blue mailman".pluralize #=> "the blue mailmen"
133
+ # "CamelOctopus".pluralize #=> "CamelOctopi"
134
+ #
135
+ def pluralize(word)
136
+ English::Inflect.plural(word)
137
+ end
138
+
139
+ end
140
+ end # module Inflection
141
+ end # module Extlib
@@ -0,0 +1,106 @@
1
+ class LazyArray # borrowed partially from StrokeDB
2
+ instance_methods.each { |m| undef_method m unless %w[ __id__ __send__ send dup class object_id kind_of? respond_to? assert_kind_of should should_not instance_variable_set instance_variable_get ].include?(m) }
3
+
4
+ include Enumerable
5
+
6
+ # these methods should return self or nil
7
+ RETURN_SELF = [ :<<, :clear, :concat, :collect!, :each, :each_index,
8
+ :each_with_index, :freeze, :insert, :map!, :push, :replace,
9
+ :reject!, :reverse!, :reverse_each, :sort!, :unshift ]
10
+
11
+ RETURN_SELF.each do |method|
12
+ class_eval <<-EOS, __FILE__, __LINE__
13
+ def #{method}(*args, &block)
14
+ lazy_load
15
+ results = @array.#{method}(*args, &block)
16
+ results.kind_of?(Array) ? self : results
17
+ end
18
+ EOS
19
+ end
20
+
21
+ (Array.public_instance_methods(false).map { |m| m.to_sym } - RETURN_SELF - [ :taguri= ]).each do |method|
22
+ class_eval <<-EOS, __FILE__, __LINE__
23
+ def #{method}(*args, &block)
24
+ lazy_load
25
+ @array.#{method}(*args, &block)
26
+ end
27
+ EOS
28
+ end
29
+
30
+ def replace(other)
31
+ mark_loaded
32
+ @array.replace(other.entries)
33
+ self
34
+ end
35
+
36
+ def clear
37
+ mark_loaded
38
+ @array.clear
39
+ self
40
+ end
41
+
42
+ def eql?(other)
43
+ lazy_load
44
+ @array.eql?(other.entries)
45
+ end
46
+
47
+ alias == eql?
48
+
49
+ def load_with(&block)
50
+ @load_with_proc = block
51
+ self
52
+ end
53
+
54
+ def loaded?
55
+ @loaded == true
56
+ end
57
+
58
+ def unload
59
+ clear
60
+ @loaded = false
61
+ self
62
+ end
63
+
64
+ def respond_to?(method, include_private = false)
65
+ super || @array.respond_to?(method, include_private)
66
+ end
67
+
68
+ def to_proc
69
+ @load_with_proc
70
+ end
71
+
72
+ private
73
+
74
+ def initialize(*args, &block)
75
+ @loaded = false
76
+ @load_with_proc = proc { |v| v }
77
+ @array = Array.new(*args, &block)
78
+ end
79
+
80
+ def initialize_copy(original)
81
+ @array = original.entries
82
+ load_with(&original)
83
+ mark_loaded if @array.any?
84
+ end
85
+
86
+ def lazy_load
87
+ return if loaded?
88
+ mark_loaded
89
+ @load_with_proc[self]
90
+ end
91
+
92
+ def mark_loaded
93
+ @loaded = true
94
+ end
95
+
96
+ # delegate any not-explicitly-handled methods to @array, if possible.
97
+ # this is handy for handling methods mixed-into Array like group_by
98
+ def method_missing(method, *args, &block)
99
+ if @array.respond_to?(method)
100
+ lazy_load
101
+ @array.send(method, *args, &block)
102
+ else
103
+ super
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,202 @@
1
+ require "time" # httpdate
2
+ # ==== Public Merb Logger API
3
+ #
4
+ # To replace an existing logger with a new one:
5
+ # Merb::Logger.set_log(log{String, IO},level{Symbol, String})
6
+ #
7
+ # Available logging levels are
8
+ # Merb::Logger::{ Fatal, Error, Warn, Info, Debug }
9
+ #
10
+ # Logging via:
11
+ # Merb.logger.fatal(message<String>,&block)
12
+ # Merb.logger.error(message<String>,&block)
13
+ # Merb.logger.warn(message<String>,&block)
14
+ # Merb.logger.info(message<String>,&block)
15
+ # Merb.logger.debug(message<String>,&block)
16
+ #
17
+ # Logging with autoflush:
18
+ # Merb.logger.fatal!(message<String>,&block)
19
+ # Merb.logger.error!(message<String>,&block)
20
+ # Merb.logger.warn!(message<String>,&block)
21
+ # Merb.logger.info!(message<String>,&block)
22
+ # Merb.logger.debug!(message<String>,&block)
23
+ #
24
+ # Flush the buffer to
25
+ # Merb.logger.flush
26
+ #
27
+ # Remove the current log object
28
+ # Merb.logger.close
29
+ #
30
+ # ==== Private Merb Logger API
31
+ #
32
+ # To initialize the logger you create a new object, proxies to set_log.
33
+ # Merb::Logger.new(log{String, IO},level{Symbol, String})
34
+ module Extlib
35
+
36
+ class << self
37
+ attr_accessor :logger
38
+ end
39
+
40
+ class Logger
41
+
42
+ attr_accessor :level
43
+ attr_accessor :delimiter
44
+ attr_accessor :auto_flush
45
+ attr_reader :buffer
46
+ attr_reader :log
47
+ attr_reader :init_args
48
+
49
+ # ==== Notes
50
+ # Ruby (standard) logger levels:
51
+ # :fatal:: An unhandleable error that results in a program crash
52
+ # :error:: A handleable error condition
53
+ # :warn:: A warning
54
+ # :info:: generic (useful) information about system operation
55
+ # :debug:: low-level information for developers
56
+ Levels =
57
+ {
58
+ :fatal => 7,
59
+ :error => 6,
60
+ :warn => 4,
61
+ :info => 3,
62
+ :debug => 0
63
+ }
64
+
65
+ private
66
+
67
+ # Readies a log for writing.
68
+ #
69
+ # ==== Parameters
70
+ # log<IO, String>:: Either an IO object or a name of a logfile.
71
+ def initialize_log(log)
72
+ close if @log # be sure that we don't leave open files laying around.
73
+
74
+ if log.respond_to?(:write)
75
+ @log = log
76
+ elsif File.exist?(log)
77
+ @log = open(log, (File::WRONLY | File::APPEND))
78
+ @log.sync = true
79
+ else
80
+ FileUtils.mkdir_p(File.dirname(log)) unless File.directory?(File.dirname(log))
81
+ @log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
82
+ @log.sync = true
83
+ @log.write("#{Time.now.httpdate} #{delimiter} info #{delimiter} Logfile created\n")
84
+ end
85
+ end
86
+
87
+ public
88
+
89
+ # To initialize the logger you create a new object, proxies to set_log.
90
+ #
91
+ # ==== Parameters
92
+ # *args:: Arguments to create the log from. See set_logs for specifics.
93
+ def initialize(*args)
94
+ @init_args = args
95
+ set_log(*args)
96
+ end
97
+
98
+ # Replaces an existing logger with a new one.
99
+ #
100
+ # ==== Parameters
101
+ # log<IO, String>:: Either an IO object or a name of a logfile.
102
+ # log_level<~to_sym>::
103
+ # The log level from, e.g. :fatal or :info. Defaults to :error in the
104
+ # production environment and :debug otherwise.
105
+ # delimiter<String>::
106
+ # Delimiter to use between message sections. Defaults to " ~ ".
107
+ # auto_flush<Boolean>::
108
+ # Whether the log should automatically flush after new messages are
109
+ # added. Defaults to false.
110
+ def set_log(log, log_level = nil, delimiter = " ~ ", auto_flush = false)
111
+ if log_level && Levels[log_level.to_sym]
112
+ @level = Levels[log_level.to_sym]
113
+ elsif Merb.environment == "production"
114
+ @level = Levels[:warn]
115
+ else
116
+ @level = Levels[:debug]
117
+ end
118
+ @buffer = []
119
+ @delimiter = delimiter
120
+ @auto_flush = auto_flush
121
+
122
+ initialize_log(log)
123
+
124
+ Merb.logger = self
125
+ end
126
+
127
+ # Flush the entire buffer to the log object.
128
+ def flush
129
+ return unless @buffer.size > 0
130
+ @log.write(@buffer.slice!(0..-1).to_s)
131
+ end
132
+
133
+ # Close and remove the current log object.
134
+ def close
135
+ flush
136
+ @log.close if @log.respond_to?(:close) && !@log.tty?
137
+ @log = nil
138
+ end
139
+
140
+ # Appends a message to the log. The methods yield to an optional block and
141
+ # the output of this block will be appended to the message.
142
+ #
143
+ # ==== Parameters
144
+ # string<String>:: The message to be logged. Defaults to nil.
145
+ #
146
+ # ==== Returns
147
+ # String:: The resulting message added to the log file.
148
+ def <<(string = nil)
149
+ message = ""
150
+ message << delimiter
151
+ message << string if string
152
+ message << "\n" unless message[-1] == ?\n
153
+ @buffer << message
154
+ flush if @auto_flush
155
+
156
+ message
157
+ end
158
+ alias :push :<<
159
+
160
+ # Generate the logging methods for Merb.logger for each log level.
161
+ Levels.each_pair do |name, number|
162
+ class_eval <<-LEVELMETHODS, __FILE__, __LINE__
163
+
164
+ # Appends a message to the log if the log level is at least as high as
165
+ # the log level of the logger.
166
+ #
167
+ # ==== Parameters
168
+ # string<String>:: The message to be logged. Defaults to nil.
169
+ #
170
+ # ==== Returns
171
+ # self:: The logger object for chaining.
172
+ def #{name}(message = nil)
173
+ self << message if #{number} >= level
174
+ self
175
+ end
176
+
177
+ # Appends a message to the log if the log level is at least as high as
178
+ # the log level of the logger. The bang! version of the method also auto
179
+ # flushes the log buffer to disk.
180
+ #
181
+ # ==== Parameters
182
+ # string<String>:: The message to be logged. Defaults to nil.
183
+ #
184
+ # ==== Returns
185
+ # self:: The logger object for chaining.
186
+ def #{name}!(message = nil)
187
+ self << message if #{number} >= level
188
+ flush if #{number} >= level
189
+ self
190
+ end
191
+
192
+ # ==== Returns
193
+ # Boolean:: True if this level will be logged by this logger.
194
+ def #{name}?
195
+ #{number} >= level
196
+ end
197
+ LEVELMETHODS
198
+ end
199
+
200
+ end
201
+
202
+ end