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 +22 -0
- data/Gemfile +2 -0
- data/LICENSE +20 -14
- data/README.md +75 -24
- data/Rakefile +1 -37
- data/lib/rmtools/{db/active_record.rb → active_record/base.rb} +7 -3
- data/lib/rmtools/active_record/declarative.rb +153 -0
- data/lib/rmtools/conversions/enum.rb +14 -2
- data/lib/rmtools/{b.rb → core/b.rb} +9 -2
- data/lib/rmtools/core/class.rb +7 -0
- data/lib/rmtools/core/js.rb +13 -10
- data/lib/rmtools/core/kernel.rb +5 -3
- data/lib/rmtools/core/proc.rb +12 -3
- data/lib/rmtools/core/symbol.rb +22 -0
- data/lib/rmtools/db.rb +1 -1
- data/lib/rmtools/dev/highlight.rb +1 -1
- data/lib/rmtools/dev/logging.rb +17 -4
- data/lib/rmtools/dev/timer.rb +6 -1
- data/lib/rmtools/dev/trace_format.rb +40 -9
- data/lib/rmtools/dev/{blackhole.rb → void.rb} +6 -4
- data/lib/rmtools/enumerable/array.rb +12 -2
- data/lib/rmtools/enumerable/array_iterators.rb +287 -44
- data/lib/rmtools/enumerable/hash.rb +1 -0
- data/lib/rmtools/enumerable/range.rb +128 -77
- data/lib/rmtools/enumerable/traversal.rb +2 -2
- data/lib/rmtools/functional/unfold.rb +6 -8
- data/lib/rmtools/rand/array.rb +16 -14
- data/lib/rmtools/time/{global.rb → helpers.rb} +0 -0
- data/lib/rmtools/version.rb +3 -0
- data/lib/rmtools.rb +10 -2
- data/lib/rmtools_dev.rb +3 -6
- data/rmtools.gemspec +28 -0
- metadata +103 -120
- data/Manifest.txt +0 -98
- data/lib/rmtools/dev/observing.rb +0 -115
- data/lib/rmtools/dev/traceback.rb +0 -41
- data/lib/rmtools/dev_min.rb +0 -2
- data/lib/rmtools/init.rb +0 -13
- data/lib/rmtools/ip.rb +0 -2
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
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
|
-
|
3
|
+
MIT License
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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,
|
5
|
-
Small dev library (in progress
|
6
|
-
Started from basic classes, now it contains low-level helpers for ActiveRecord and makes LibXML more
|
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
|
9
|
-
`hash[
|
10
|
-
`ary.map(&:id)` -> `ary.ids`
|
11
|
-
`ary.map {|h| h[
|
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
|
-
####
|
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
|
-
*
|
32
|
-
*
|
33
|
-
*
|
34
|
-
*
|
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
|
-
*
|
42
|
-
*
|
43
|
-
*
|
44
|
-
* Added
|
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
|
-
*
|
48
|
-
*
|
49
|
-
*
|
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
|
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
|
-
|
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
|
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
|
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
|
data/lib/rmtools/core/class.rb
CHANGED
data/lib/rmtools/core/js.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
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[
|
22
|
-
(a == default) ? self[
|
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[
|
29
|
-
(a == default) ? self[
|
31
|
+
a = self[:type]
|
32
|
+
(a == default) ? self['type'] : a
|
30
33
|
end
|
31
34
|
def id
|
32
|
-
a = self[
|
33
|
-
(a == default) ? self[
|
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
|
data/lib/rmtools/core/kernel.rb
CHANGED
@@ -3,9 +3,11 @@ module Kernel
|
|
3
3
|
|
4
4
|
# re-require
|
5
5
|
def require!(file)
|
6
|
-
[
|
7
|
-
|
8
|
-
|
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
|
|
data/lib/rmtools/core/proc.rb
CHANGED
@@ -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
|
-
|
16
|
-
|
17
|
-
|
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
|
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
|
-
"#{
|
29
|
+
"#{to_s}#{@string ? ': '+Painter.green(@string) : source_location && ": \n"+RMTools.highlighted_line(*source_location)}"
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|