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 +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
|