rmtools 1.3.3 → 2.0.0.rc5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ Manifest.txt
19
+ Makefile
20
+ *.out
21
+ *.o
22
+ *.so
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE CHANGED
@@ -1,16 +1,22 @@
1
- Copyright (c) 2010-2013
2
- Sergey Baev <tinbka@gmail.com>
1
+ Copyright (c) 2010-2013 Sergey Baev <tinbka@gmail.com>
3
2
 
4
- This work is licensed under the same license as Ruby language.
3
+ MIT License
5
4
 
6
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
7
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
10
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
11
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
12
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16
- SUCH DAMAGE.
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,52 +1,103 @@
1
1
  ### RMTools
2
2
  [github](https://github.com/tinbka/rmtools)
3
3
 
4
- Collection of helpers for any need: strings, enumerables, Module... hundreds of bicycles, shortcuts you ever wanted to implement is here, optimized for performance.
5
- Small dev library (in progress for ever): fast and smart logger, binding explorer, backtrace formatter, all are console-colored.
6
- Started from basic classes, now it contains low-level helpers for ActiveRecord and makes LibXML more jQueryish.
4
+ Collection of helpers for any need: strings, enumerables, modules... hundreds of bicycles and shortcuts you ever wanted to implement are here, optimized for performance.
5
+ Small dev library (constantly in progress): fast and smart logger, binding explorer, backtrace formatter, each is console-colored.
6
+ Started from basic classes, now it contains low-level helpers for ActiveRecord and makes LibXML more jqueryish.
7
7
 
8
- RMTools is based on opinion that some boiler-plate should be thrown away from Ruby making it more expressive with no (0~10%) performance penalty:
9
- `hash['id']` -> `hash.id`
10
- `ary.map(&:id)` -> `ary.ids`
11
- `ary.map {|h| h['id']}` -> `ary.ids`
12
- `comments.posts.sorted_uniq_by_id.select_by_user_id(user_id).sum_points` -> `comments.map {|c| c.post}.sort_by {|p| p.id}.uniq_by {|p| p.id}.select {|p| p.user_id == user_id}.sum {|p| p.points}`
8
+ RMTools helps to throw away some boiler-plate making a code more intuitive. It comes with almost no (<< 10%) performance penalty:
9
+ * `hash[:id]` -> `hash.id`
10
+ * `ary.map(&:id)` -> `ary.ids`
11
+ * `ary.map {|h| h[:id]}` -> `ary.ids`
12
+ * `comments.posts.sorted_uniq_by_id.select_by_user_id(user_id).sum_points` -> `comments.map {|c| c.post}.sort_by {|p| p.id}.uniq_by {|p| p.id}.select {|p| p.user_id == user_id}.sum {|p| p.points}`
13
13
 
14
14
  ---
15
15
 
16
16
  It's still randomly documented since it's just my working tool.
17
17
 
18
- #### Expected to complete:
18
+ #### Wanted to implement
19
+
20
+ * Ruby code parser (StringScanner-based) reading an array of loaded ruby-files and making accurate hash-table of defined methods {"Class#method" => "def ... end"}
21
+ * JSON-formatter for output ruby objects content in HTML presentation in order to inspect big objects using browser graphic abilities
22
+ * Set theory based Range extension with support of both begin and end exclusion, and satisfying the next rules:
23
+ * `size(0..1) = size(0...1) = 1`
24
+ * `A = A - B | B`
25
+ * `A ⊃ B -> size(A - B) = size(A) - size(B)`
19
26
 
20
- * Ruby code parser (StringScanner-based) reading array of loaded ruby-files and making accurate hash-table of defined methods {"Class#method" => "def ... end"}
21
- * JSON-formatter for output ruby objects content in HTML form in order to inspect big objects using browser abilities
22
- * Redis addon (inspired by redis-objects): store and search relations, data-typing. (maybe I'll create another gem for that)
23
27
 
24
28
  ### CHANGES
25
29
 
30
+ ##### Version 2.0.0
31
+
32
+ * Array Meta-iterators
33
+ * Pattern has became a class variable. New names can be added to pattern by Array::add_iterator_name
34
+ * Speed has been drastically boosted by evaluating of every proper missing method. (Read comments in /enumerable/array_iterators.rb)
35
+ * Using meta-iterators in the new behaviour can smudge Array instance_methods namespace. Although it's not something that bad, that's possible to turn on the old behaviour by Array::fallback_to_clean_iterators!
36
+
37
+ * Hash#method_missing
38
+ * hash.something gets hash[:something] || hash['something'], not other way
39
+ * hash.something= sets hash['something'] as did it before
40
+ * This change has been caused by large amounts of symbolic options keys and json decode returning symbolic keys (at least with a yajl library).
41
+ * Set behaviour, on the other hand, will not be changed since 1) it will be too hard to debug hashes in an old code; 2) it's not that frequently used; 3) setting hash key directly by :[]= makes a code clearer
42
+
43
+ * Class
44
+ * Added private #alias_constant
45
+
46
+ * Array
47
+ * #avg and #avg_by for an empty array now return 0
48
+ * Fixed #rand_by for an empty array
49
+ * Added #intersects? aliased as #x?
50
+
51
+ * Symbol
52
+ * Added #+, #split and #method_missing to proxy all possible methods to #to_s
53
+
54
+ * Range
55
+ * Specified a concept of the extension (/enumerable/range.rb)
56
+ * Changed default Range#include? the way it can take range as argument
57
+ * Added XRange#first(count) and #last(count), analogically to Range#first and #last
58
+
59
+ * ActiveRecord
60
+ * Moved declarative.rb from Rhack project. ::Base::declarative is a way of making tables like by migrations but on the fly
61
+ * Added ::Base#with_same(<column_name>)
62
+ * ::Base::non_null_scopes ignores non-nullable columns
63
+
64
+ * Development kit
65
+ * RMTools::timer now resets $quiet and $log.mute_warn to previous values in case of ^C or another exception raised
66
+ * Fixed all potential problems with /dev, so require "rmtools_dev" is deprecated in favour of require "rmtools" and will be removed in the next update
67
+ * Read comments about format_trace in /dev/trace_format.rb
68
+ * BlackHole class is aliased as Void
69
+ * Added :detect_comments and :precede_comments options to ::RMLogger to automatically highlight comment blocks get logged
70
+
71
+ * Structural changes
72
+ * Moved /b.rb into /core since #b is proved usability through some years
73
+ * Renamed /db into /active_record
74
+ * Merged /ip into /conversions
75
+ * The gem is now being produced in the bundle style: added Gemfile, .gemspec, etc
76
+
26
77
  ##### Version 1.3.3
27
78
 
28
79
  * Added to Array: #sort_along_by, #indices_map, #each_two
29
- * Enumerable#map_hash
80
+ * Added Enumerable#map_hash
30
81
  * Range
31
- * * Fixed #size for backward ranges
32
- * * Fixed #x? and #-@ for neighbor numbers and non-integers in general
33
- * * added XRange#x?
34
- * * aliased #x? as #intersects?
82
+ * Fixed #size for backward ranges
83
+ * Fixed #x? and #-@ for neighbor numbers and non-integers in general
84
+ * added XRange#x?
85
+ * aliased #x? as #intersects?
35
86
  * Class#__init__ accepts block, auto__init__ed Thread and Proc
36
87
 
37
88
  ##### Version 1.3.0
38
89
 
39
90
  * Added ::ValueTraversal and ::KeyValueTraversal modules for treeish dir/enumerable search
40
91
  * String
41
- * * Cyrillic support: #fupcase, #fdowncase and instant up/down versions
42
- * * #to_search, #squeeze_newlines, #recordize
43
- * * key :js_caller to #parse for JS stacktrace lines as it given by stacktrace.js library
44
- * Added AR::Base::boolean_scopes! and ::non_null_scopes!
92
+ * Cyrillic support: #fupcase, #fdowncase and instant up/down versions
93
+ * #to_search, #squeeze_newlines, #recordize
94
+ * key :js_caller to #parse for JS stacktrace lines as it given by stacktrace.js library
95
+ * Added ActiveRecord::Base::boolean_scopes! and ::non_null_scopes!
45
96
  * Added Object#ifndef for ivars caching
46
97
  * Fixed bugs
47
- * * Class#__init__ (case with nested classes)
48
- * * AR::Base::select_rand (case with :where query)
49
- * * ::rw and ::write (cases with encoding fail and non-string argument)
98
+ * Class#__init__ (case with nested classes)
99
+ * ActiveRecord::Base::select_rand (case with :where query)
100
+ * ::rw and ::write (cases with encoding fail and non-string argument)
50
101
  * Described the library and *marked down* this readme
51
102
 
52
103
  ##### Version 1.2.14
data/Rakefile CHANGED
@@ -1,37 +1 @@
1
- require 'rake'
2
- require './lib/rmtools/install'
3
- compile_manifest
4
-
5
- RMTOOLS_VERSION = '1.3.3'
6
- begin
7
- require 'hoe'
8
- config = Hoe.spec 'rmtools' do |h|
9
- h.developer("Sergey Baev", "tinbka@gmail.com")
10
-
11
- #self.summary = 'Yet another Ruby applied lib'
12
- h.description = 'Applied library primarily for debug and text/arrays/files processing purposes.'
13
- h.urls = ['https://github.com/tinbka/rmtools']
14
-
15
- h.extra_deps = [['rake','>= 0.8.7'], ['activesupport','>= 2.3.8']]
16
- end
17
- config.spec.extensions << 'ext/extconf.rb'
18
- rescue LoadError
19
- STDERR.puts "cannot load the Hoe gem. Distribution is disabled"
20
- rescue Exception => e
21
- STDERR.puts "cannot load the Hoe gem, or Hoe fails. Distribution is disabled"
22
- STDERR.puts "error message is: #{e.message}"
23
- end
24
-
25
- ruby = RbConfig::CONFIG['RUBY_INSTALL_NAME']
26
- windoze = RUBY_PLATFORM =~ /mswin32/
27
- make = windoze ? 'nmake' : 'make'
28
-
29
- Dir.chdir "ext" do
30
- unless system "#{ruby} extconf.rb #{ENV['EXTCONF_OPTS']}" and system make
31
- # don't we have a compiler?
32
- warn "failed to compile extension, continuing installation without extension"
33
- end
34
- if File.file? 'Makefile'
35
- system "#{make} clean" and FileUtils.rm_f "Makefile"
36
- end
37
- end unless ext_files_not_modified 'rmtools', RMTOOLS_VERSION
1
+ require "bundler/gem_tasks"
@@ -18,6 +18,7 @@ module ActiveRecord
18
18
  end
19
19
 
20
20
  class Base
21
+ class_attribute :enums
21
22
 
22
23
  class << self
23
24
 
@@ -87,7 +88,6 @@ module ActiveRecord
87
88
  ) i", options])
88
89
  end
89
90
 
90
- class_attribute :enums
91
91
  # virtual (only-in-ruby) "enum" type support
92
92
  def enum hash
93
93
  key = hash.keys.first
@@ -119,12 +119,12 @@ module ActiveRecord
119
119
  # including zero and empty string
120
120
  def non_null_scopes!
121
121
  boolean_scopes!
122
- columns.names.to_syms.each {|col|
122
+ columns.select_null.names.to_syms.each {|col|
123
123
  unless respond_to? col
124
124
  scope col, where("#{quoted_table_name}.#{col} is not null")
125
125
  end
126
126
  }
127
- rescue
127
+ rescue
128
128
  nil
129
129
  end
130
130
 
@@ -168,6 +168,10 @@ module ActiveRecord
168
168
  "#{self.class.name.tableize}/#{id}"
169
169
  end
170
170
 
171
+ def with_same(attr)
172
+ self.class.where(attr => self[attr])
173
+ end
174
+
171
175
  end
172
176
 
173
177
  class Relation
@@ -0,0 +1,153 @@
1
+ # encoding: utf-8
2
+ module ActiveRecord
3
+
4
+ module ConnectionAdapters
5
+ AbstractAdapter
6
+
7
+ class VirtualTable < Table
8
+
9
+ def debug_str meth, called, exist, *args
10
+ "Table.#{meth}(#{args.inspects*', '}) was#{' NOT' if !called} called due to #{'in' if !exist}existance"
11
+ end
12
+
13
+ def column_exists *args
14
+ column_names = @base.columns(@table_name).names
15
+ options = args.extract_options!
16
+ names = args.dup
17
+ args << options
18
+ _or_ = (names[0] == :all) ? !names.shift : true
19
+ names.each {|name| return _or_ if name.to_s.in(column_names) == _or_}
20
+ !_or_
21
+ end
22
+
23
+ def index_exists *indexes
24
+ column_indexes = @base.indexes(@table_name).columnss.flatten
25
+ _or_ = (indexes[0] == :all) ? !indexes.shift : true
26
+ indexes.each {|index| return _or_ if index.to_s.in(column_indexes) == _or_}
27
+ !_or_
28
+ end
29
+
30
+ def initialize name, connection, map=nil
31
+ super name, connection
32
+ case map
33
+ when true; @map = []
34
+ when Array; @map = map
35
+ end
36
+ end
37
+
38
+ def map!
39
+ map_names = @map.firsts.to_ss
40
+ @base.columns(@table_name).names.each {|name|
41
+ name.in(map_names) ? @map.reject! {|_| _[0] == name} : remove(name)
42
+ }
43
+ @map.each {|col| column *col}
44
+ end
45
+
46
+ def column name, *args
47
+ to_be_called = !column_exists(name)
48
+ super if to_be_called
49
+ $log.debug {debug_str :column, to_be_called, !to_be_called, name, *args}
50
+ @map << [name, *args] if @map
51
+ end
52
+
53
+ %w{string text integer float decimal
54
+ datetime timestamp time date binary boolean}.each {|column_type|
55
+ define_method(column_type) {|*args|
56
+ to_be_called = !column_exists(*args)
57
+ super if to_be_called
58
+ $log.debug {debug_str column_type, to_be_called, !to_be_called, *args}
59
+ if @map
60
+ options = args.extract_options!
61
+ args = args.xprod(column_type)
62
+ args = args.xprod(options) if options
63
+ @map.concat args
64
+ end
65
+ } }
66
+
67
+ def index name, *args
68
+ to_be_called = !index_exists(name)
69
+ super if to_be_called
70
+ $log.debug {debug_str :index, to_be_called, !to_be_called, name, *args}
71
+ end
72
+
73
+ def timestamps
74
+ to_be_called = !column_exists('created_at', 'updated_at')
75
+ super if to_be_called
76
+ $log.debug {debug_str :timestamps, to_be_called, !to_be_called}
77
+ @map.concat [[:created_at, :datetime], [:updated_at, :datetime]] if @map
78
+ end
79
+
80
+ def change *args
81
+ raise NotImplementedError, "don't use #change in declaration!"
82
+ end
83
+
84
+ def change_default *args
85
+ raise NotImplementedError, "don't use #change_default in declaration!"
86
+ end
87
+
88
+ def rename column_name, new_column_name
89
+ to_be_called = !column_exists(new_column_name)
90
+ super if to_be_called
91
+ $log.debug {debug_str :rename, to_be_called, !to_be_called, column_name, new_column_name}
92
+ end
93
+
94
+ def references *args
95
+ to_be_called = !column_exists(*args.map {|col| "#{col}_id"})
96
+ super if to_be_called
97
+ $log.debug {debug_str :references, to_be_called, !to_be_called, *args}
98
+ end
99
+ alias :belongs_to :references
100
+
101
+ def remove *args
102
+ to_be_called = column_exists :all, *args
103
+ super if to_be_called
104
+ $log.debug {debug_str :remove, to_be_called, to_be_called, *args}
105
+ end
106
+
107
+ def remove_references *args
108
+ to_be_called = column_exists(:all, *args.map {|col| "#{col}_id"})
109
+ super if to_be_called
110
+ $log.debug {debug_str :remove_references, to_be_called, to_be_called, *args}
111
+ end
112
+ alias :remove_belongs_to :remove_references
113
+
114
+ def remove_index options
115
+ indexes = options.is(Hash) ? options[:column] : options
116
+ raise ArgumentError, "can remove only default format named indexes in declaration!" if !indexes
117
+ to_be_called = index_exists :all, *indexes
118
+ super if to_be_called
119
+ $log.debug {debug_str :remove_index, to_be_called, to_be_called, options}
120
+ end
121
+
122
+ def remove_timestamps
123
+ to_be_called = column_exists 'created_at', 'updated_at'
124
+ super if to_be_called
125
+ $log.debug {debug_str :remove_timestamps, to_be_called, to_be_called}
126
+ end
127
+
128
+ end
129
+
130
+ end
131
+
132
+ class << Base
133
+
134
+ def declare(name, options={}, &block)
135
+ self.table_name = name
136
+ if !table_exists? or options[:force]
137
+ $log < "with options[:force] the `#{table_name}` table will have been recreated each time you load the #{model_name} model" if options[:force]
138
+ self.primary_key = options[:primary_key] if options[:id] != false and options[:primary_key]
139
+ $log.debug "connection.create_table(#{name}, #{options.inspect}) {}"
140
+ connection.create_table(name, options, &block)
141
+ elsif options[:map]
142
+ table = ConnectionAdapters::VirtualTable.new(name, connection, options[:map])
143
+ yield table
144
+ table.map!
145
+ else yield ConnectionAdapters::VirtualTable.new(name, connection)
146
+ end
147
+ reset_column_information
148
+ end
149
+
150
+ end
151
+
152
+ end
153
+
@@ -1,11 +1,23 @@
1
1
  # encoding: utf-8
2
- #require 'cgi'
3
2
 
4
3
  module Enumerable
5
4
 
6
- # Simple http stringifying. Also stringifies multi-value hashes
5
+ # Simple http stringifying:
6
+ # {'a'=>10, 'b'=>20}.urlencode
7
+ # => "a=10&b=20"
8
+ # Stringifies hashes with multi-value values:
7
9
  # {'a'=>'10&20&30'}.urlencode
10
+ # or
11
+ # {'a'=>[10, 20, 30]}.urlencode
8
12
  # => "a=10&a=20&a=30"
13
+ # Stringifies hashes with multi-value keys as well:
14
+ # {['a', 'b']=>[10, 20]}.urlencode
15
+ # => "a=10&a=20&b=10&b=20"
16
+ # Stringifies hashes with hash-value values:
17
+ # {'a'=>{0=>10, 'b'=>{'c'=>20, 'd'=>30}}}.urlencode
18
+ # => "a[0]=10&a[b]=20"
19
+
20
+ # TODO: deal with it
9
21
  def urlencode
10
22
  map {|k, v| next if !v
11
23
  k, v = k.to_s, v.to_s
@@ -1,22 +1,29 @@
1
- # encoding: utf-8
2
1
  # {obj.b -> self or false} with python logic
3
- # Since 2.3.8 active_support has analogue: #presence
2
+ # Since 2.3.8 ActiveSupport has similar method: #presence
3
+ # Though, #b is obviously more usable due to it's length,
4
+ # and still intuitive: "Boolean", "Being", "to Be"
5
+ # Differs from #presence in that String#b do not use #strip for check
4
6
 
5
7
  class Object
6
8
  def b; self end
7
9
  end
10
+
8
11
  class Numeric
9
12
  def b; !zero? && self end
10
13
  end
14
+
11
15
  class String
12
16
  def b; !empty? && self end
13
17
  end
18
+
14
19
  class Proc
15
20
  def b; (self != NULL) && self end
16
21
  end
22
+
17
23
  class NilClass
18
24
  def b; false end
19
25
  end
26
+
20
27
  module Enumerable
21
28
  def b; !empty? && self end
22
29
  end
@@ -51,6 +51,13 @@ class Class
51
51
  end
52
52
  end
53
53
 
54
+ def alias_constant(name)
55
+ class_eval %{
56
+ def #{name}(key=nil)
57
+ key ? self.class::#{name}[key] : self.class::#{name}
58
+ end}
59
+ end
60
+
54
61
  end
55
62
 
56
63
  require 'set'
@@ -1,5 +1,6 @@
1
1
  # encoding: utf-8
2
- # js hash getter/setter and string concat logic
2
+
3
+ # Javascript hash getter/setter and string concat logic
3
4
  class Hash
4
5
  alias :throw_no :method_missing
5
6
 
@@ -11,6 +12,8 @@ class Hash
11
12
  # hash.unknown_function # => nil
12
13
  # hash[:def] = 456
13
14
  # hash.def # => 456
15
+ #
16
+ # This priority should be stable, because
14
17
  def method_missing(method, *args)
15
18
  str = method.to_s
16
19
  if str =~ /=$/
@@ -18,19 +21,19 @@ class Hash
18
21
  elsif !args.empty? or str =~ /[!?]$/
19
22
  throw_no method
20
23
  else
21
- a = self[str]
22
- (a == default) ? self[method] : a
24
+ a = self[method]
25
+ (a == default) ? self[str] : a
23
26
  end
24
27
  end
25
28
 
26
29
  # Redefine since these methods are deprecated anyway
27
30
  def type
28
- a = self['type']
29
- (a == default) ? self[:type] : a
31
+ a = self[:type]
32
+ (a == default) ? self['type'] : a
30
33
  end
31
34
  def id
32
- a = self['id']
33
- (a == default) ? self[:id] : a
35
+ a = self[:id]
36
+ (a == default) ? self['id'] : a
34
37
  end
35
38
 
36
39
  end
@@ -42,13 +45,13 @@ class String
42
45
  # immutable:
43
46
  # '123' + 95 # => '12395'
44
47
  # '123'.plus 95 # => raise TypeError
45
- # mutable:
46
- # '123' << 95 # => '12395'
47
- # '123'.concat 95 # => '123_'
48
48
  def +(str)
49
49
  plus str.to_s
50
50
  end
51
51
 
52
+ # mutable:
53
+ # '123' << 95 # => '12395'
54
+ # '123'.concat 95 # => '123_'
52
55
  def <<(str)
53
56
  concat str.to_s
54
57
  end
@@ -3,9 +3,11 @@ module Kernel
3
3
 
4
4
  # re-require
5
5
  def require!(file)
6
- ['.rb', '.so', '.dll', ''].each {|ext| $".delete "#{file}#{ext}"}
7
- file = File.expand_path file
8
- ['.rb', '.so', '.dll', ''].each {|ext| $".delete "#{file}#{ext}"}
6
+ [file, File.expand_path(file)].find {|path|
7
+ ['.rb', '.so', '.dll', ''].find {|ext|
8
+ $".delete "#{file}#{ext}"
9
+ }
10
+ } || $".del_where {|path| path[%r{/#{file}(.rb|.so|.dll)?$}]}
9
11
  require file
10
12
  end
11
13
 
@@ -3,6 +3,7 @@ class Proc
3
3
  NULL = lambda {|*x|} unless defined? Proc::NULL
4
4
  TRUE = lambda {|*x| true} unless defined? Proc::TRUE
5
5
  FALSE = lambda {|*x| false} unless defined? Proc::FALSE
6
+ SELF = lambda {|x| x} unless defined? Proc::FALSE
6
7
  attr_accessor :string
7
8
 
8
9
  def when
@@ -12,9 +13,17 @@ class Proc
12
13
  end
13
14
  end
14
15
 
15
- def self.eval string, binding=nil
16
- (proc = (binding || Kernel).eval "lambda {#{string}}").string = string
17
- proc
16
+ class << self
17
+
18
+ def eval string, binding=nil
19
+ (proc = (binding || Kernel).eval "lambda {#{string}}").string = string
20
+ proc
21
+ end
22
+
23
+ def self; SELF end
24
+ def noop; NULL end
25
+ def true; TRUE end
26
+ def false; FALSE end
18
27
  end
19
28
 
20
29
  if RUBY_VERSION < '1.9'
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ class Symbol
3
+
4
+ def +(str)
5
+ to_s + str
6
+ end
7
+
8
+ def split(splitter='_')
9
+ to_s.split splitter
10
+ end
11
+ alias :/ :split
12
+
13
+ alias :throw_no :method_missing
14
+ def method_missing(method, *args, &block)
15
+ if ''.respond_to? method
16
+ to_s.__send__ method, *args, &block
17
+ else
18
+ throw_no method
19
+ end
20
+ end
21
+
22
+ end
data/lib/rmtools/db.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  begin
3
3
  require 'active_record'
4
4
  ActiveRecord::Base
5
- RMTools::require __FILE__, 'active_record'
5
+ RMTools::require 'active_record/*'
6
6
  # fix for that mystic bug
7
7
  # /usr/lib/ruby/1.8/openssl/ssl-internal.rb:30: [BUG] Segmentation fault
8
8
  # ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-linux]
@@ -26,7 +26,7 @@ end
26
26
  class Proc
27
27
 
28
28
  def inspect
29
- "#{str=to_s}: #{@string ? Painter.green(@string) : "\n"+RMTools.highlighted_line(*source_location)}"
29
+ "#{to_s}#{@string ? ': '+Painter.green(@string) : source_location && ": \n"+RMTools.highlighted_line(*source_location)}"
30
30
  end
31
31
 
32
32
  end