gemmyrb 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57241faae027cf6e4416104dcedd95dcdb6f3d56
4
- data.tar.gz: 6f4caf998b97cd0e9fdc84f243f19813248e0541
3
+ metadata.gz: 959c5dce4ee3611f0e6a9a1ee91a8da5ed128b3b
4
+ data.tar.gz: 2a2349bd342e424e17246d58d951b6e99dd74538
5
5
  SHA512:
6
- metadata.gz: 2fef2f0b535f1829842689b3c6d5dc92cbf223dac26ea3b0dceb60476a075309e59e3ee3be8e25b93b198734bc2e8c15f8c3a5030cfb4cb21a832fb13ddc51d5
7
- data.tar.gz: ce6f3a3f1c5d7b54eac6e72fc1341bf3748a6926bc054cda10d6512e7905a22ca87d291ddd6c6dc8a485e70fb05750c42c1b0b6bc7a14e7a44125190bc16c4f3
6
+ metadata.gz: 7115fb4d4a8f4a152be9e24ac51bfd120101cd73d69d3356579aeda8526a83e7f77b99362571fdd2d1646849b0b6bbe703d34619f1234077b51245b61efcacd5
7
+ data.tar.gz: dc1d6dafb2a9e55032622f6aebbd38e540a6ba55998f1d3aa3048a71248fd50dfe9ef228e394c5072290ae8de90afadbc350d350e26ca14a596f549bef402207
data/README.md CHANGED
@@ -19,7 +19,12 @@ documents:
19
19
  - _Loading the gem's code in different scopes_
20
20
  - [examples/01_using_as_refinement.rb](./examples/01_using_as_refinement.rb)
21
21
  - [examples/02_using_globally.rb](./examples/02_using_globally.rb)
22
- - _List of methods intended for general Ruby use_
23
- - [examples/03_ruby_extensions_list.rb](./examples/03_ruby_extensions_list.rb)
24
22
  - _Shell commands and other one-off processes_
25
- - [examples/04_shell_commands.rb](./examples/04_shell_commands.rb)
23
+ - [examples/03_shell_commands.rb](./examples/03_shell_commands.rb)
24
+
25
+ **To see a full list of the patched methods (there are a lot since I've
26
+ included many from facets), see the [rubydoc](http://www.rubydoc.info/gems/gemmyrb)**
27
+
28
+ Specifically, look at the constants defined on Gemmy::Patches. There is one
29
+ module for each of the core classes being patched. Each individual method
30
+ is also contained in its own module (to make modular inclusion possible)
@@ -6,7 +6,7 @@ module Gemmy::Patches::ArrayPatch
6
6
 
7
7
  module Zip
8
8
  # facets
9
- def self.zip(*arrays)
9
+ def zip(*arrays)
10
10
  return [] if arrays.empty?
11
11
  return arrays[0].zip(*arrays[1..-1])
12
12
  end
@@ -16,6 +16,14 @@ module Gemmy::Patches::ArrayPatch
16
16
 
17
17
  module InstanceMethods
18
18
 
19
+ module Exclude
20
+ # facets
21
+ # the opposite of include
22
+ def exclude?(x)
23
+ ! include? x
24
+ end
25
+ end
26
+
19
27
  module KeyBy
20
28
  # facets
21
29
  def key_by
@@ -0,0 +1,14 @@
1
+ module Gemmy::Patches::ClassPatch
2
+ module InstanceMethods
3
+ module ToProc
4
+ # facets
5
+ # I.e if an initializer takes one arg, then you can do
6
+ # %w{ arg1 arg2 }.map &ClassToInitialize
7
+ def to_proc
8
+ proc{|*args| new(*args)}
9
+ end
10
+ end
11
+ end
12
+ module ClassMethods
13
+ end
14
+ end
@@ -0,0 +1,40 @@
1
+ module Gemmy::Patches::ExceptionPatch
2
+
3
+ module ClassMethods
4
+
5
+ module Raised
6
+ # facets
7
+ # does an exception raise an error?
8
+ def self.raised? #:yeild:
9
+ begin
10
+ yield
11
+ false
12
+ rescue self
13
+ true
14
+ end
15
+ end
16
+ end
17
+
18
+ module Suppress
19
+ # facets
20
+ def suppress(*err_classes)
21
+ err_classes.each do |e|
22
+ unless e < self
23
+ raise ArgumentError, "exception #{e} not a subclass of #{self}"
24
+ end
25
+ end
26
+ err_classes = err_classes.empty? ? [self] : err_classes
27
+ begin
28
+ yield
29
+ rescue Exception => e
30
+ raise unless err_classes.any? { |cls| e.kind_of?(cls) }
31
+ end
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ module InstanceMethods
38
+ end
39
+
40
+ end
@@ -0,0 +1,16 @@
1
+ module Gemmy::Patches::FloatPatch
2
+ module ClassMethods
3
+ end
4
+ module InstanceMethods
5
+
6
+ module RoundTo
7
+ # facets
8
+ # i.e. 2.046.round_to(0.01) == 2.05
9
+ def round_to( n ) #n=1
10
+ return self if n == 0
11
+ (self * (1.0 / n)).round.to_f / (1.0 / n)
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -3,10 +3,194 @@
3
3
  module Gemmy::Patches::HashPatch
4
4
 
5
5
  module ClassMethods
6
+ # facets
7
+ # Hash.zip(["a","b","c"], [1,2,3])
8
+ # => { "a"=>1, "b"=>2, "c"=>3 }
9
+ module Zip
10
+ def zip(keys,values) # or some better name
11
+ h = {}
12
+ keys.size.times{ |i| h[ keys[i] ] = values[i] }
13
+ h
14
+ end
15
+ end
6
16
  end
7
17
 
8
18
  module InstanceMethods
9
19
 
20
+ module UpdateKeys
21
+ # facets
22
+ # in place
23
+ def update_keys #:yield:
24
+ if block_given?
25
+ keys.each { |old_key| store(yield(old_key), delete(old_key)) }
26
+ else
27
+ to_enum(:update_keys)
28
+ end
29
+ end
30
+ end
31
+
32
+ module UpdateValues
33
+ # facets
34
+ # in place
35
+ def update_values #:yield:
36
+ if block_given?
37
+ each{ |k,v| store(k, yield(v)) }
38
+ else
39
+ to_enum(:update_values)
40
+ end
41
+ end
42
+ end
43
+
44
+ module ToOpenStruct
45
+ # facets
46
+ def to_ostruct
47
+ OpenStruct.new(self)
48
+ end
49
+ def recursive_to_ostruct(exclude={})
50
+ return exclude[self] if exclude.key?( self )
51
+ o = exclude[self] = OpenStruct.new
52
+ h = self.dup
53
+ each_pair do |k,v|
54
+ h[k] = v.to_ostruct_recurse( exclude ) if v.respond_to?(:to_ostruct_recurse)
55
+ end
56
+ o.merge!(h)
57
+ end
58
+ end
59
+
60
+ module Rekey
61
+ # facets
62
+ # rekey according to a block, i.e. {a: 1}.rekey &:to_s
63
+ def rekey(key_map=nil, &block)
64
+ raise ArgumentError, "argument or block" if key_map && block
65
+
66
+ if !(key_map or block)
67
+ block = lambda{|k| k.to_sym}
68
+ end
69
+
70
+ if block
71
+ hash = dup.clear
72
+ if block.arity.abs == 1
73
+ each_pair do |k, v|
74
+ hash[block[k]] = v #hash[block[k] || k] = v
75
+ end
76
+ else
77
+ each_pair do |k, v|
78
+ hash[block[k,v]] = v #hash[block[k,v] || k] = v
79
+ end
80
+ end
81
+ else
82
+ #hash = dup.clear # to keep default_proc
83
+ #(keys - key_map.keys).each do |key|
84
+ # hash[key] = self[key]
85
+ #end
86
+ #key_map.each do |from, to|
87
+ # hash[to] = self[from] if key?(from)
88
+ #end
89
+ hash = dup # to keep default_proc
90
+ key_map.each_pair do |from, to|
91
+ hash[to] = hash.delete(from) if hash.key?(from)
92
+ end
93
+ end
94
+
95
+ hash
96
+ end
97
+ end
98
+
99
+ module Recurse
100
+ # facets
101
+ # h = {:a=>1, :b=>{:b1=>1, :b2=>2}}
102
+ # g = h.recurse{|h| h.inject({}){|h,(k,v)| h[k.to_s] = v; h} }
103
+ # g #=> {"a"=>1, "b"=>{"b1"=>1, "b2"=>2}}
104
+ def recurse(*types, &block)
105
+ types = [self.class] if types.empty?
106
+ h = inject({}) do |hash, (key, value)|
107
+ case value
108
+ when *types
109
+ hash[key] = value.recurse(*types, &block)
110
+ else
111
+ hash[key] = value
112
+ end
113
+ hash
114
+ end
115
+ yield h
116
+ end
117
+ end
118
+
119
+ module HasKeys
120
+ # facets
121
+ # checks if a list of keys are all present
122
+ def keys?(*check_keys)
123
+ unknown_keys = check_keys - self.keys
124
+ return unknown_keys.empty?
125
+ end
126
+ end
127
+
128
+ module OnlyKeys
129
+ # facets
130
+ # checks if these are the only keys
131
+ def only_keys?(*check_keys)
132
+ unknown_keys = self.keys - check_keys
133
+ return unknown_keys.empty?
134
+ end
135
+ end
136
+
137
+ module Join
138
+ # facets
139
+ # returns a string
140
+ def join(pair_divider='', elem_divider=nil)
141
+ elem_divider ||= pair_divider
142
+ s = []
143
+ each{ |k,v| s << "#{k}#{pair_divider}#{v}" }
144
+ s.join(elem_divider)
145
+ end
146
+ end
147
+
148
+ module Inverse
149
+ # facets
150
+ # h = {"a"=>3, "b"=>3, "c"=>3, "d"=>2, "e"=>9, "f"=>3, "g"=>9}
151
+ # h.invert #=> {2=>"d", 3=>"f", 9=>"g"}
152
+ # h.inverse #=> {2=>"d", 3=>["f", "c", "b", "a"], 9=>["g", "e"]}
153
+ # h.inverse.inverse #=> {"a"=>3, "b"=>3, "c"=>3, "d"=>2, "e"=>9, "f"=>3, "g"=>9}
154
+ def inverse
155
+ i = Hash.new
156
+ self.each_pair{ |k,v|
157
+ if (Array === v)
158
+ v.each{ |x| i[x] = ( i.has_key?(x) ? [k,i[x]].flatten : k ) }
159
+ else
160
+ i[v] = ( i.has_key?(v) ? [k,i[v]].flatten : k )
161
+ end
162
+ }
163
+ return i
164
+ end
165
+ end
166
+
167
+ module Diff
168
+ # facets
169
+ # returns the key-vals from <self> that are not the same in <hash>
170
+ def diff(hash)
171
+ h1 = self.dup.delete_if{ |k,v| hash[k] == v }
172
+ h2 = hash.dup.delete_if{ |k,v| has_key?(k) }
173
+ h1.merge(h2)
174
+ end
175
+ end
176
+
177
+ module Except
178
+ # facets
179
+ # excludes vertain keys
180
+ def except(*less_keys)
181
+ hash = dup
182
+ less_keys.each{ |k| hash.delete(k) }
183
+ hash
184
+ end
185
+ end
186
+
187
+ module DeleteUnless
188
+ # facets
189
+ def delete_unless #:yield:
190
+ delete_if{ |key, value| ! yield(key, value) }
191
+ end
192
+ end
193
+
10
194
  # The opposite of Hash#dig
11
195
  # Takes a list of keys followed by a value to set
12
196
  #
@@ -2,6 +2,27 @@ module Gemmy::Patches::IntegerPatch
2
2
 
3
3
  module ClassMethods
4
4
 
5
+ module RomanValues
6
+ # facets
7
+ def roman_values
8
+ [
9
+ ["M", 1000],
10
+ ["CM", 900],
11
+ ["D", 500],
12
+ ["CD", 400],
13
+ ["C", 100],
14
+ ["XC", 90],
15
+ ["L", 50],
16
+ ["XL", 40],
17
+ ["X", 10],
18
+ ["IX", 9],
19
+ ["V", 5],
20
+ ["IV", 4],
21
+ ["I", 1]
22
+ ].to_h
23
+ end
24
+ end
25
+
5
26
  end
6
27
 
7
28
  module InstanceMethods
@@ -1,12 +1,203 @@
1
1
  # Object patches. Can be called with implicit receiver
2
2
  #
3
+ # Patches which are originally specified as being for Kernel (by facets,
4
+ # for examples), are implemented here as patches on Object because Kernel is
5
+ # a module and Ruby doesn't support refinements on Modules. Object includes
6
+ # and extends Kernel so it's the same effect.
7
+ #
3
8
  module Gemmy::Patches::ObjectPatch
4
9
 
10
+ # This class is redundant here, since Object's instance methods
11
+ # are available at the class scope anyway.
5
12
  module ClassMethods
6
13
  end
7
14
 
8
15
  module InstanceMethods
9
16
 
17
+ module Iteself
18
+ # facets
19
+ def itself
20
+ def itself
21
+ self
22
+ end
23
+ end
24
+ end
25
+
26
+ module Try
27
+ # facets
28
+ # nicer than the builtin
29
+ # @example.try.name #=> "bob"
30
+ # @people.try(:collect){ |p| p.name }
31
+ def try(method=nil, *args, &block)
32
+ if method
33
+ __send__(method, *args, &block)
34
+ else
35
+ self
36
+ end
37
+ end
38
+ end
39
+
40
+ module Not
41
+ # facets
42
+ # true.nil?.not? == !true.nil?
43
+ def not?
44
+ !self
45
+ end
46
+ end
47
+
48
+ module Truthy
49
+ def truthy
50
+ !! self
51
+ end
52
+ end
53
+
54
+ module Falsy
55
+ def Falsy
56
+ ! self
57
+ end
58
+ end
59
+
60
+ module NotNil
61
+ # facets
62
+ def not_nil?
63
+ ! nil?
64
+ end
65
+ end
66
+
67
+ module Maybe
68
+ # Random generator that returns true or false. Can also take a block that has a 50/50 chance to being executed…
69
+ # facets
70
+ def maybe(chance = 0.5, &block)
71
+ if block
72
+ yield if rand < chance
73
+ else
74
+ rand < chance
75
+ end
76
+ end
77
+ end
78
+
79
+ module InstanceAssign
80
+ # facets
81
+ # assign instance variables with a hash
82
+ def instance_assign(hash)
83
+ hash.each do |k,v|
84
+ k = "@#{k}" if k !~ /^@/
85
+ instance_variable_set(k, v)
86
+ end
87
+ self
88
+ end
89
+ end
90
+
91
+ module HierarchicalSend
92
+ # facets
93
+ # Send a message to each ancestor in an object's class hierarchy. The method will only be called if the method is defined for the ancestor.
94
+ # This can be very useful for setting up a `preinitialize` system.
95
+ #
96
+ # Example:
97
+ # m = Module.new do
98
+ # attr :a
99
+ # def preinitialize
100
+ # @a = 1
101
+ # end
102
+ # end
103
+ #
104
+ # c = Class.new do
105
+ # include m
106
+ # def initialize
107
+ # hierarchical_send(:preinitialize)
108
+ # end
109
+ # end
110
+
111
+ # c.new.a #=> 1
112
+ def hierarchical_send(method_name, *args, &block)
113
+ method_name = method_name.to_s if RUBY_VERSION < '1.9'
114
+ this = self
115
+ self.class.hierarchically do |anc|
116
+ ## is there really no better way to check for the method?
117
+ if anc.instance_methods(false).include?(method_name) or
118
+ anc.public_instance_methods(false).include?(method_name) or
119
+ anc.private_instance_methods(false).include?(method_name) or
120
+ anc.protected_instance_methods(false).include?(method_name)
121
+ im = anc.instance_method(method_name)
122
+ ##im.arity == 0 ? im.bind(this).call(&block) : im.bind(this).call(*args, &block)
123
+ im.bind(this).call(*args, &block)
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ module Ergo
130
+ # facets
131
+ # This is like #tap, but #tap yields self and returns self,
132
+ # where as #ergo yields self but returns the result.
133
+ def ergo(&b)
134
+ if block_given?
135
+ b.arity > 0 ? yield(self) : instance_eval(&b)
136
+ else
137
+ self
138
+ end
139
+ end
140
+ end
141
+
142
+ module DeepCopy
143
+ # facets
144
+ def deep_copy
145
+ Marshal::load(Marshal::dump(self))
146
+ end
147
+ end
148
+
149
+ module Constant
150
+ # facets
151
+ # like Module#const_get accessible at all levels
152
+ # and handles module hierarchy.
153
+ # constant("Process::Sys")
154
+ def constant(const)
155
+ const = const.to_s.dup
156
+ base = const.sub!(/^::/, '') ? Object : ( self.kind_of?(Module) ? self : self.class )
157
+ const.split(/::/).inject(base){ |mod, name| mod.const_get(name) }
158
+ end
159
+ end
160
+
161
+ module Bool
162
+ # facets
163
+ def bool?
164
+ (true == self or false == self)
165
+ end
166
+ end
167
+
168
+ module AttrSingletonAccessor
169
+ # facets
170
+ # obj = Object.new
171
+ # obj.attr_singleton_accessor :x, :y
172
+ def attr_singleton_accessor(*args)
173
+ #h, a = *args.partition{|a| Hash===a}
174
+ (class << self ; self ; end).send( :attr_accessor, *args )
175
+ #(class << self ; self ; end).send( :attr_accessor, *h.keys )
176
+ #h.each { |k,v| instance_variable_set("@#{k}", v) }
177
+ end
178
+ end
179
+
180
+ module AttrSingletonReader
181
+ # facets
182
+ def attr_singleton_reader(*args)
183
+ #h, a = *args.partition{|a| Hash===a}
184
+ (class << self ; self ; end).send( :attr_reader, *args )
185
+ #(class << self ; self ; end).send( :attr_reader, *h.keys )
186
+ #h.each { |k,v| instance_variable_set("@#{k}", v) }
187
+ end
188
+ end
189
+
190
+ module AttrSingletonWriter
191
+ # facets
192
+ def attr_singleton_writer(*args)
193
+ #h, a = *args.partition{|a| Hash===a}
194
+ (class << self ; self ; end).send( :attr_writer, *args )
195
+ #(class << self ; self ; end).send( :attr_writer, *h.keys )
196
+ #h.each { |k,v| instance_variable_set("@#{k}", v) }
197
+ end
198
+ end
199
+
200
+
10
201
  # Turns on verbose mode, showing warnings
11
202
  #
12
203
  module VerboseMode
@@ -24,6 +215,15 @@ module Gemmy::Patches::ObjectPatch
24
215
  end
25
216
  end
26
217
 
218
+ module Ask
219
+ # facets
220
+ def ask(prompt=nil)
221
+ $stdout << "#{prompt}"
222
+ $stdout.flush
223
+ $stdin.gets.chomp!
224
+ end
225
+ end
226
+
27
227
  # Prints a string then gets input
28
228
  # @param txt [String]
29
229
  #
@@ -0,0 +1,83 @@
1
+ module Gemmy::Patches::ProcPatch
2
+ module ClassMethods
3
+ end
4
+ module InstanceMethods
5
+
6
+ module ToMethod
7
+ # facets
8
+ # converts a proc to a method on an object
9
+ # object = Object.__new__
10
+ # function = lambda { |x| x + 1 }
11
+ # function.to_method(object, 'foo')
12
+ # object.foo(1) #=> 2
13
+ def to_method(object, name=nil)
14
+ ##object = object || eval("self", self)
15
+ block, time = self, Time.now
16
+ method_name = name || "__bind_#{time.to_i}_#{time.usec}"
17
+ begin
18
+ object.singleton_class.class_eval do
19
+ define_method(method_name, &block)
20
+ method = instance_method(method_name)
21
+ remove_method(method_name) unless name
22
+ method
23
+ end.bind(object)
24
+ rescue TypeError
25
+ object.class.class_eval do
26
+ define_method(method_name, &block)
27
+ method = instance_method(method_name)
28
+ remove_method(method_name) unless name
29
+ method
30
+ end.bind(object)
31
+ end
32
+ end
33
+ end
34
+
35
+ # facets
36
+ # can be used for higher-order methods
37
+ # a = lambda { |x| x + 4 }
38
+ # b = lambda { |y| y / 2 }
39
+
40
+ # (a * b).call(4) #=> 6
41
+ # (b * a).call(4) #=> 4
42
+ module Multiply
43
+ def *(x)
44
+ if Integer===x
45
+ # collect times
46
+ c = []
47
+ x.times{|i| c << call(i)}
48
+ c
49
+ else
50
+ # compose procs
51
+ lambda{|*a| self[x[*a]]}
52
+ end
53
+ end
54
+ end
55
+
56
+ module Compose
57
+ # facets
58
+ # similar to multiply
59
+ #
60
+ # a = lambda { |x| x + 4 }
61
+ # b = lambda { |y| y / 2 }
62
+
63
+ # a.compose(b).call(4) #=> 6
64
+ # b.compose(a).call(4) #=> 4
65
+ def compose(g)
66
+ raise ArgumentError, "arity count mismatch" unless arity == g.arity
67
+ lambda{ |*a| self[ *g[*a] ] }
68
+ end
69
+ end
70
+
71
+ module BindTo
72
+ # facets
73
+ # a = [1,2,3]
74
+ # p1 = Proc.new{ join(' ') }
75
+ # p2 = p1.bind_to(a)
76
+ # p2.call #=> '1 2 3'
77
+ def bind_to(object)
78
+ Proc.new{object.instance_eval(&self)}
79
+ end
80
+ end
81
+
82
+ end
83
+ end
@@ -7,6 +7,223 @@ module Gemmy::Patches::StringPatch
7
7
 
8
8
  module InstanceMethods
9
9
 
10
+ module Words
11
+ # facets
12
+ def words
13
+ self.split(/\s+/)
14
+ end
15
+ end
16
+
17
+ module Rotate
18
+ # facets
19
+ # 'abcdefgh'.rotate(2) #=> 'cdefghab'
20
+ # 'abcdefgh'.rotate(-2) #=> 'ghabcdef'
21
+ def rotate(count=1)
22
+ count+=self.length if count<0
23
+ self.slice(count,self.length-count)+self.slice(0,count)
24
+ end
25
+ end
26
+
27
+ module Range
28
+ # facets
29
+ # Gets the start/end indexes of a match to <pattern>
30
+ # only considers first match
31
+ def range(pattern, offset=0)
32
+ unless Regexp === pattern
33
+ pattern = Regexp.new(Regexp.escape(pattern.to_s))
34
+ end
35
+ string = self[offset..-1]
36
+ if md = pattern.match(string)
37
+ return (md.begin(0)+offset)..(md.end(0)+offset-1)
38
+ end
39
+ nil
40
+ end
41
+ end
42
+
43
+ module RangeAll
44
+ # facets
45
+ # like #range patch but returns start/end indexes of all matches
46
+ def range_all(pattern, reuse=false)
47
+ r = []; i = 0
48
+ while i < self.length
49
+ rng = range(pattern, i)
50
+ if rng
51
+ r << rng
52
+ i += reuse ? 1 : rng.end + 1
53
+ else
54
+ break
55
+ end
56
+ end
57
+ r.uniq
58
+ end
59
+ end
60
+
61
+ module IsNumber
62
+ # facets
63
+ def is_number?
64
+ !!self.match(/\A[+-]?\d+?(_?\d+?)*?(\.\d+(_?\d+?)*?)?\Z/)
65
+ end
66
+ end
67
+
68
+ module EachMatch
69
+ # facets
70
+ # iterator over matches from regex
71
+ def each_match(re) #:yield:
72
+ if block_given?
73
+ scan(re) { yield($~) }
74
+ else
75
+ m = []
76
+ scan(re) { m << $~ }
77
+ m
78
+ end
79
+ end
80
+ end
81
+
82
+ module LineWrap
83
+ # facets
84
+ # wrap lines at width
85
+ def line_wrap(width, tabs=4)
86
+ s = gsub(/\t/,' ' * tabs) # tabs default to 4 spaces
87
+ s = s.gsub(/\n/,' ')
88
+ r = s.scan( /.{1,#{width}}/ )
89
+ r.join("\n") << "\n"
90
+ end
91
+ end
92
+
93
+ module Lchomp
94
+ # facets
95
+ def lchomp(match)
96
+ if index(match) == 0
97
+ self[match.size..-1]
98
+ else
99
+ self.dup
100
+ end
101
+ end
102
+ end
103
+
104
+ module IndexAll
105
+ # facets
106
+ # standard String#index only shows the first match
107
+ def index_all(s, reuse=false)
108
+ s = Regexp.new(Regexp.escape(s)) unless Regexp===s
109
+ ia = []; i = 0
110
+ while (i = index(s,i))
111
+ ia << i
112
+ i += (reuse ? 1 : $~[0].size)
113
+ end
114
+ ia
115
+ end
116
+ end
117
+
118
+ module Indent
119
+ # facets
120
+ def indent(n, c=' ')
121
+ if n >= 0
122
+ gsub(/^/, c * n)
123
+ else
124
+ gsub(/^#{Regexp.escape(c)}{0,#{-n}}/, "")
125
+ end
126
+ end
127
+ end
128
+
129
+ module ExpandTabs
130
+ # turns tabs to spaces
131
+ def expand_tabs(n=8)
132
+ n = n.to_int
133
+ raise ArgumentError, "n must be >= 0" if n < 0
134
+ return gsub(/\t/, "") if n == 0
135
+ return gsub(/\t/, " ") if n == 1
136
+ str = self.dup
137
+ while
138
+ str.gsub!(/^([^\t\n]*)(\t+)/) { |f|
139
+ val = ( n * $2.size - ($1.size % n) )
140
+ $1 << (' ' * val)
141
+ }
142
+ end
143
+ str
144
+ end
145
+ end
146
+
147
+ module Exclude
148
+ # facets
149
+ def exclude?(str)
150
+ !include?(str)
151
+ end
152
+ end
153
+
154
+ module CompressLines
155
+ # facets
156
+ # replace newlines or N spaces with one space
157
+ def compress_lines(spaced = true)
158
+ split($/).map{ |line| line.strip }.join(spaced ? ' ' : '')
159
+ end
160
+ end
161
+
162
+ module AlignCenter
163
+ # facets
164
+ def align_center(n, sep="\n", c=' ')
165
+ return center(n.to_i,c.to_s) if sep==nil
166
+ q = split(sep.to_s).collect { |line|
167
+ line.center(n.to_i,c.to_s)
168
+ }
169
+ q.join(sep.to_s)
170
+ end
171
+ end
172
+
173
+ module AlignLeft
174
+ # facets
175
+ def align_left(n, sep="\n", c=' ')
176
+ return ljust(n.to_i,c.to_s) if sep==nil
177
+ q = split(sep.to_s).map do |line|
178
+ line.strip.ljust(n.to_i,c.to_s)
179
+ end
180
+ q.join(sep.to_s)
181
+ end
182
+ end
183
+
184
+ module AsciiOnly
185
+ # facets
186
+ # remove non ascii characters
187
+ def ascii_only(alt='')
188
+ encoding_options = {
189
+ :invalid => :replace, # Replace invalid byte sequences
190
+ :undef => :replace, # Replace anything not defined in ASCII
191
+ :replace => alt, # Use a blank for those replacements
192
+ :UNIVERSAL_NEWLINE_DECORATOR => true # Always break lines with \n
193
+ }
194
+ self.encode(Encoding.find('ASCII'), encoding_options)
195
+ end
196
+ end
197
+
198
+ module AlignRight
199
+ # facets
200
+ def align_right(n, sep="\n", c=' ')
201
+ return rjust(n.to_i,c.to_s) if sep==nil
202
+ q = split(sep.to_s).map do |line|
203
+ line.rjust(n.to_i,c.to_s)
204
+ end
205
+ q.join(sep.to_s)
206
+ end
207
+ end
208
+
209
+ module Subtract
210
+ # facets
211
+ # removes all instances of a pattern from a string
212
+ def -(pattern)
213
+ gsub(pattern, '')
214
+ end
215
+ end
216
+
217
+ module Random
218
+ # facets
219
+ # a random string of length n with a given character set
220
+ def self.random(len=32, character_set = ["A".."Z", "a".."z", "0".."9"])
221
+ characters = character_set.map { |i| i.to_a }.flatten
222
+ characters_len = characters.length
223
+ (0...len).map{ characters[rand(characters_len)] }.join
224
+ end
225
+ end
226
+
10
227
  # reference 'strip_heredoc' (provided by active support) by 'unindent'
11
228
  #
12
229
  # this takes an indented heredoc and treats it as if the first line is not
@@ -5,7 +5,16 @@ module Gemmy::Patches::SymbolPatch
5
5
  module ClassMethods
6
6
  end
7
7
 
8
- module InstanceMethods
8
+ module InstanceMethods
9
+
10
+ module Variablize
11
+ # facets
12
+ # take a symbol and make it fine for an instance variable name
13
+ def variablize
14
+ name = to_s.gsub(/\W/, '_')
15
+ "@#{name}".to_sym
16
+ end
17
+ end
9
18
 
10
19
  # Patch symbol so the proc shorthand can take extra arguments
11
20
  # http://stackoverflow.com/a/23711606/2981429
data/lib/gemmy/patches.rb CHANGED
@@ -95,7 +95,11 @@ module Gemmy::Patches
95
95
  Method: Gemmy::Patches::MethodPatch,
96
96
  Hash: Gemmy::Patches::HashPatch,
97
97
  Thread: Gemmy::Patches::ThreadPatch,
98
- Integer: Gemmy::Patches::IntegerPatch
98
+ Integer: Gemmy::Patches::IntegerPatch,
99
+ Class: Gemmy::Patches::ClassPatch,
100
+ Exception: Gemmy::Patches::ExceptionPatch,
101
+ Float: Gemmy::Patches::FloatPatch,
102
+ Proc: Gemmy::Patches::ProcPatch
99
103
  }.with_indifferent_access
100
104
  end
101
105
 
data/lib/gemmy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Gemmy
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemmyrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - max pleaner
@@ -101,10 +101,14 @@ files:
101
101
  - lib/gemmy/components/dynamic_steps.rb
102
102
  - lib/gemmy/patches.rb
103
103
  - lib/gemmy/patches/array_patch.rb
104
+ - lib/gemmy/patches/class_patch.rb
105
+ - lib/gemmy/patches/exception_patch.rb
106
+ - lib/gemmy/patches/float_patch.rb
104
107
  - lib/gemmy/patches/hash_patch.rb
105
108
  - lib/gemmy/patches/integer_patch.rb
106
109
  - lib/gemmy/patches/method_patch.rb
107
110
  - lib/gemmy/patches/object_patch.rb
111
+ - lib/gemmy/patches/proc_patch.rb
108
112
  - lib/gemmy/patches/string_patch.rb
109
113
  - lib/gemmy/patches/symbol_patch.rb
110
114
  - lib/gemmy/patches/thread_patch.rb