gemmyrb 0.0.3 → 0.0.4

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