rmtools 1.3.3 → 2.0.0.rc5

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/.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