cldwalker-my_core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ The MIT LICENSE
2
+
3
+ Copyright (c) 2009 Gabriel Horner
4
+
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.
@@ -0,0 +1,31 @@
1
+ == Description
2
+
3
+ My collection of extensions to Ruby's core and stdlib classes.
4
+
5
+ == Install
6
+
7
+ gem install cldwalker-my_core -s http://github.com/cldwalker/my_core
8
+
9
+ == Usage
10
+
11
+ Since all these extensions are wrapped in modules you need to require
12
+ the extension you want and then include/extend it into your desired class.
13
+ I don't automatically monkeypatch your classes. You have the choice
14
+ to monkeypatch or not.
15
+
16
+ To use the instance methods of my Array extension.
17
+
18
+ require 'my_core/object'
19
+ Object.send :include, MyCore::Array
20
+
21
+ To use the class methods of my File extension.
22
+
23
+ require 'my_core/file'
24
+ Object.send :extend, MyCore::File
25
+
26
+ If you'd like a more convient way of loading multiple extensions in this library,
27
+ see my core gem: http://github.com/cldwalker/core .
28
+
29
+ == Todo
30
+
31
+ Tests!
@@ -0,0 +1,49 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ begin
5
+ require 'rcov/rcovtask'
6
+
7
+ Rcov::RcovTask.new do |t|
8
+ t.libs << 'test'
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ t.rcov_opts = ["-T -x '/Library/Ruby/*'"]
11
+ t.verbose = true
12
+ end
13
+ rescue LoadError
14
+ puts "Rcov not available. Install it for rcov-related tasks with: sudo gem install rcov"
15
+ end
16
+
17
+ begin
18
+ require 'jeweler'
19
+ Jeweler::Tasks.new do |s|
20
+ s.name = "my_core"
21
+ s.description = "My extensions to core ruby classes, similar to activesupport and facets gems."
22
+ s.summary = s.description
23
+ s.email = "gabriel.horner@gmail.com"
24
+ s.homepage = "http://github.com/cldwalker/my_core"
25
+ s.authors = ["Gabriel Horner"]
26
+ s.files = FileList["VERSION.yml", "Rakefile", "README.rdoc", "LICENSE.txt", "{bin,lib}/**/*"]
27
+ s.has_rdoc = true
28
+ s.extra_rdoc_files = ["README.rdoc", "LICENSE.txt" ]
29
+ end
30
+
31
+ rescue LoadError
32
+ puts "Jeweler not available. Install it for jeweler-related tasks with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
33
+ end
34
+
35
+ Rake::TestTask.new do |t|
36
+ t.libs << 'lib'
37
+ t.pattern = 'test/**/*_test.rb'
38
+ t.verbose = false
39
+ end
40
+
41
+ Rake::RDocTask.new do |rdoc|
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = 'test'
44
+ rdoc.options << '--line-numbers' << '--inline-source'
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
48
+
49
+ task :default => :test
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 1
4
+ :patch: 0
@@ -0,0 +1,5 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module MyCore
5
+ end
@@ -0,0 +1,116 @@
1
+ module MyCore
2
+ module Array
3
+ # Allows you to specify ranges of elements and individual elements with one string, array starts at 1
4
+ # Example: choose first and fourth through eighth elements: '1,4-8'
5
+ def multislice(range,splitter=',',offset=nil)
6
+ #td: fix swallowing of empty lines
7
+ result = []
8
+ for r in range.split(splitter)
9
+ if r =~ /-/
10
+ min,max = r.split('-')
11
+ slice_min = min.to_i - 1
12
+ slice_min += offset if offset
13
+ result.push(*self.slice(slice_min, max.to_i - min.to_i + 1))
14
+ else
15
+ index = r.to_i - 1
16
+ index += offset if offset
17
+ result.push(self[index])
18
+ end
19
+ end
20
+ return result
21
+ end
22
+
23
+ # Converts an even # of array elements ie [1,2,3,4]
24
+ # or an array of array pairs ie [[1,2],[3,4]] to a hash.
25
+ def to_hash
26
+ Hash[*self.flatten]
27
+ end
28
+
29
+ # Returns hash mapping elements to the number of times they are found in the array.
30
+ def count_hash
31
+ count = {}
32
+ each {|e|
33
+ count[e] ||= 0
34
+ count[e] += 1
35
+ }
36
+ count
37
+ end
38
+
39
+ # Returns all possible paired permutations of elements disregarding order.
40
+ def permute
41
+ permutations = []
42
+ for i in (0 .. self.size - 1)
43
+ for j in (i + 1 .. self.size - 1)
44
+ permutations.push([self[i],self[j]])
45
+ end
46
+ end
47
+ permutations
48
+ end
49
+
50
+ # Assuming the array is an array of hashes, this returns a hash of the elements grouped by their
51
+ # values for the specified hash key.
52
+ def group_aoh_by_key(key,parallel_array=nil)
53
+ group = {}
54
+ each_with_index {|h,i|
55
+ value = h[key]
56
+ group[value] = [] if ! group.has_key?(value)
57
+ group[value].push((parallel_array.nil?) ? h : parallel_array[i])
58
+ }
59
+ group
60
+ end
61
+
62
+ # Maps the result of calling each element with the given method name and optional arguments.
63
+ def mmap(methodname,*args)
64
+ map {|e| e.send(methodname,*args) }
65
+ end
66
+
67
+ # Maps the result of calling the given function name with each element as its argument.
68
+ def fmap(function)
69
+ (function =~ /\./) ?
70
+ map {|e| eval "#{function}(e)" } :
71
+ map {|e| send(function,e) }
72
+ end
73
+
74
+ # Returns index of first element to match given regular expression.
75
+ def regindex(regex)
76
+ each_with_index {|e,i|
77
+ return i if e =~ /#{regex}/
78
+ }
79
+ nil
80
+ end
81
+
82
+ # Replaces element at index with values of given array.
83
+ def replace_index(i,array)
84
+ replace( (self[0, i] || []) + array + self[i + 1 .. -1] )
85
+ end
86
+
87
+ # Returns true if the array includes any from the first array and excludes all from the second.
88
+ def include_and_exclude?(do_include,dont_include=[])
89
+ include_any?(do_include) && exclude_all?(dont_include)
90
+ end
91
+
92
+ # Returns true if it has any elements in common with the given array.
93
+ def include_any?(arr)
94
+ #good for large sets w/ few matches
95
+ #! Set.new(self).intersection(arr).empty?
96
+ arr.any? {|e| self.include?(e) }
97
+ end
98
+
99
+
100
+ # Returns true if it has no elements in common with the given array.
101
+ def exclude_all?(arr)
102
+ ! include_any?(arr)
103
+ end
104
+
105
+ # A real array def, not a set diff
106
+ # a1 = [1,1,2]
107
+ # a2 = [1,2]
108
+ # a1 - a2 #=> []
109
+ # a1.diff(a2) #=> [1]
110
+ def diff(other)
111
+ list = self.dup
112
+ other.each { |elem| list.delete_at( list.index(elem) ) }
113
+ list
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,33 @@
1
+ module MyCore
2
+ module Class
3
+ # Returns ancestors that aren't included modules and the class itself.
4
+ def real_ancestors
5
+ ancestors - included_modules - [self]
6
+ end
7
+
8
+ #Returns all objects of class.
9
+ def objects
10
+ object = []
11
+ ObjectSpace.each_object(self) {|e| object.push(e) }
12
+ object
13
+ end
14
+
15
+ #td: used to be :objects, change tb_* files to reflect change
16
+ def object_strings #:nodoc:
17
+ objects.map {|e| e.to_s}
18
+ end
19
+
20
+ def eigenclass
21
+ instance_eval("class << self; self; end")
22
+ end
23
+
24
+ # gaining temporary access to private methods
25
+ # http://blog.jayfields.com/2007/11/ruby-testing-private-methods.html
26
+ def publicize_methods
27
+ saved_private_instance_methods = self.private_instance_methods
28
+ self.class_eval { public *saved_private_instance_methods }
29
+ yield
30
+ self.class_eval { private *saved_private_instance_methods }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,67 @@
1
+ # All methods here take an optional directory argument, defaulting to the current directory.
2
+ module MyCore
3
+ module Dir
4
+ module ClassMethods
5
+ # Returns current directory with a '/' appended.
6
+ def mpwd
7
+ ::Dir.pwd + "/"
8
+ end
9
+
10
+ # Returns entries from simple_entries() that are directories.
11
+ def dir_children(dirname=mpwd)
12
+ simple_entries(dirname).find_all {|e|
13
+ File.directory?(File.join(dirname, e))
14
+ }
15
+ end
16
+
17
+ # Returns entries from simple_entries() that are files.
18
+ def file_children(dirname=mpwd)
19
+ simple_entries(dirname).find_all {|e|
20
+ File.file?(File.join(dirname,e))
21
+ }
22
+ end
23
+
24
+ # Returns everything in a directory that entries() would except
25
+ # for '.', '..' and vim's backup files ie files ending with ~ or .sw*.
26
+ # You should override this method to take advantage of methods based on it.
27
+ def simple_entries(dirname=mpwd)
28
+ dir_files = ::Dir.entries(dirname)
29
+ files = dir_files - ['.','..'] - dir_files.grep(/~$/) - dir_files.grep(/\.sw[o-z]$/)
30
+ end
31
+
32
+ # Returns entries from simple_entries() that are not symlinks.
33
+ def nonlink_entries(dirname=mpwd)
34
+ simple_entries(dirname).select {|e|
35
+ ! File.symlink?(File.join(dirname,e))
36
+ }
37
+ end
38
+
39
+ #Returns the full paths of simple_entries().
40
+ def full_entries(dirname=mpwd)
41
+ simple_entries(dirname).map {|e| File.join(dirname,e) }
42
+ end
43
+
44
+ # Returns all simple_entries under a directory for the specified depth. If no depth specified
45
+ # it'll return all entries under the directory.
46
+ def levels_of_children(dirname=mpwd,max_level=1000)
47
+ @max_level = max_level
48
+ @level_children = []
49
+ get_level_children(dirname,0)
50
+ @level_children
51
+ end
52
+
53
+ #used recursively by levels_of_children
54
+ def get_level_children(dirname,level) #:nodoc:
55
+ dir_children = full_entries(dirname)
56
+ @level_children += dir_children
57
+ if level < @max_level
58
+ dir_children.each {|e|
59
+ if File.directory?(e)
60
+ get_level_children(e,level + 1)
61
+ end
62
+ }
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,25 @@
1
+ module MyCore
2
+ module File
3
+ module ClassMethods
4
+ # Converts file to string.
5
+ def to_string(file)
6
+ IO.read(file)
7
+ end
8
+
9
+ # Writes string to file.
10
+ def string_to_file(string,file)
11
+ File.open(file,'w') {|f| f.write(string) }
12
+ end
13
+
14
+ #mac only: http://stream.btucker.org/post/65635235/file-creation-date-in-ruby-on-macs
15
+ def creation_time(file)
16
+ require 'open3'
17
+ require 'time'
18
+ Time.parse( Open3.popen3("mdls",
19
+ "-name","kMDItemContentCreationDate",
20
+ "-raw", file)[1].read)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,83 @@
1
+ module MyCore
2
+ module Hash
3
+ # For a hash whose keys are strings of Class names, this will delete any pairs that have
4
+ # nonexistant class names.
5
+ def validate_value_klass(klass)
6
+ self.each {|sid,obj|
7
+ if obj.class != Object.const_get(klass)
8
+ warn "object of '#{sid}' not a #{klass}"
9
+ self.delete(sid)
10
+ end
11
+ }
12
+ end
13
+
14
+ # Returns a hash which will set its values by calling each value with the given method and optional argument.
15
+ # If a block is passed, each value will be set the value returned by its block call.
16
+ def vmap(arg=nil,method='[]',&block)
17
+ new = {}
18
+ if block
19
+ self.each {|k,v|
20
+ v1 = yield(k,v)
21
+ new[k] = v1
22
+ }
23
+ else
24
+ self.each {|k,v|
25
+ new[k] = arg.nil? ? v.send(method) : v.send(method,arg)
26
+ }
27
+ end
28
+ new
29
+ end
30
+
31
+ # Same as vmap() but merges its results with the existing hash.
32
+ def vmap!(*args,&block)
33
+ self.update(vmap(*args,&block))
34
+ end
35
+
36
+ # For a hash whose values are arrays, this will return a hash with each value substituted by the
37
+ # size of the value.
38
+ def vsize
39
+ vmap(nil,'size')
40
+ end
41
+
42
+ # Same as pass_keys!() but replaces the hash with the resulting hash.
43
+ def only_keep(arr=[],opt={})
44
+ delete_keys!(self.keys - arr,opt)
45
+ end
46
+
47
+ def delete_keys!(arr=[],opt={}) #:nodoc:
48
+ deleted = {}
49
+ arr.each {|e|
50
+ puts "deleting #{e}" if opt[:verbose]
51
+ deleted[e] = self.delete(e) if has_key?(e)
52
+ }
53
+ deleted
54
+ end
55
+
56
+ # Returns a subset of the hash for the specified keys. These entries will be deleted from the
57
+ # original hash.
58
+ def pass_keys!(*keys)
59
+ delete_keys!(keys)
60
+ end
61
+
62
+ # For a hash whose values are arrays, this will set each unique element in a value array as a key
63
+ # and set its values to all the keys it occurred in.
64
+ # This is useful when modeling one to many relationships with keys
65
+ # and values.
66
+ def transform_many
67
+ b = {}
68
+ each {|k,arr|
69
+ #raise "#{arr.inspect} not an Array" if arr.class != Array
70
+ arr = [arr] if arr.class != Array
71
+ arr.each {|e|
72
+ b.has_key?(e) ? b[e].push(k) : b[e] = [k]
73
+ }
74
+ }
75
+ b
76
+ end
77
+
78
+ #Sorts hash by values, returning them as an array of array pairs.
79
+ def vsort
80
+ sort { |a,b| b[1]<=>a[1] }
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,24 @@
1
+ module MyCore
2
+ module IO
3
+ module ClassMethods
4
+ #Returns array of lines up until the given string matches a line of the file.
5
+ def read_until(file,string)
6
+ f = readlines(file)
7
+ i = f.index(string) || 100000
8
+ f.slice(0,i)
9
+ end
10
+
11
+ #from output_catcher gem
12
+ def capture_stdout(&block)
13
+ original_stdout = $stdout
14
+ $stdout = fake = StringIO.new
15
+ begin
16
+ yield
17
+ ensure
18
+ $stdout = original_stdout
19
+ end
20
+ fake.string
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ #from http://errtheblog.com/posts/9-drop-to-irb
2
+ # call with IRB.start_session(Kernel.binding) in script
3
+ require 'irb'
4
+
5
+ module IRB
6
+ module ClassMethods
7
+ def start_session(binding)
8
+ IRB.setup(nil)
9
+
10
+ workspace = WorkSpace.new(binding)
11
+
12
+ if @CONF[:SCRIPT]
13
+ irb = Irb.new(workspace, @CONF[:SCRIPT])
14
+ else
15
+ irb = Irb.new(workspace)
16
+ end
17
+
18
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
19
+ @CONF[:MAIN_CONTEXT] = irb.context
20
+
21
+ trap("SIGINT") do
22
+ irb.signal_handle
23
+ end
24
+
25
+ catch(:IRB_EXIT) do
26
+ irb.eval_input
27
+ end
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,33 @@
1
+ module MyCore
2
+ module Object
3
+
4
+ module ClassMethods
5
+ # A more versatile version of Object.const_get.
6
+ # Retrieves constant for given string, even if it's nested under classes.
7
+ def any_const_get(name)
8
+ begin
9
+ klass = Object
10
+ name.split('::').each {|e|
11
+ klass = klass.const_get(e)
12
+ }
13
+ klass
14
+ rescue; nil; end
15
+ end
16
+ end
17
+
18
+ #Reloads a file just as you would require it.
19
+ def reload(filename)
20
+ $".delete(filename + ".rb")
21
+ require(filename)
22
+ end
23
+
24
+ # list methods which aren't in superclass
25
+ def local_methods(obj = self)
26
+ (obj.methods - obj.class.superclass.instance_methods).sort
27
+ end
28
+
29
+ def backtick(cmd,*args)
30
+ IO.popen('-') {|f| f ? f.read : exec(cmd,*args)}
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ require 'ostruct'
2
+
3
+ # Explained http://tagaholic.blogspot.com/2009/01/simple-block-to-hash-conversion-for.html
4
+ module MyCore
5
+ module OpenStruct
6
+ module ClassMethods
7
+ def block_to_hash(block=nil)
8
+ config = self.new
9
+ if block
10
+ block.call(config)
11
+ config.to_hash
12
+ else
13
+ {}
14
+ end
15
+ end
16
+ end
17
+
18
+ def to_hash
19
+ @table
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ module MyCore
2
+ module Regexp
3
+ # Convenience method on Regexp so you can do
4
+ # /an/.show_match("banana")
5
+ # stolen from the pickaxe
6
+ def show_regexp(a, re)
7
+ if a =~ re
8
+ "#{$`}<<#{$&}>>#{$'}"
9
+ else
10
+ "no match"
11
+ end
12
+ end
13
+ def show_match(a)
14
+ show_regexp(a, self)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module MyCore
2
+ module String
3
+ # Counts # of times the given string is in the string. This is unlike String.count which
4
+ # only counts the given characters.
5
+ def count_any(str)
6
+ count = 0
7
+ self.gsub(str) {|s|
8
+ count += 1
9
+ str
10
+ }
11
+ count
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ module MyCore
2
+ module Symbol
3
+ # Enable items.map(&:name) a la Rails
4
+ def to_proc
5
+ lambda {|*args| args.shift.__send__(self, *args)}
6
+ end
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cldwalker-my_core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gabriel Horner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-02 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: My extensions to core ruby classes, similar to activesupport and facets gems.
17
+ email: gabriel.horner@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - LICENSE.txt
25
+ files:
26
+ - VERSION.yml
27
+ - Rakefile
28
+ - README.rdoc
29
+ - LICENSE.txt
30
+ - lib/my_core
31
+ - lib/my_core/array.rb
32
+ - lib/my_core/class.rb
33
+ - lib/my_core/dir.rb
34
+ - lib/my_core/file.rb
35
+ - lib/my_core/hash.rb
36
+ - lib/my_core/io.rb
37
+ - lib/my_core/irb.rb
38
+ - lib/my_core/object.rb
39
+ - lib/my_core/open_struct.rb
40
+ - lib/my_core/regexp.rb
41
+ - lib/my_core/string.rb
42
+ - lib/my_core/symbol.rb
43
+ - lib/my_core.rb
44
+ has_rdoc: true
45
+ homepage: http://github.com/cldwalker/my_core
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.2.0
67
+ signing_key:
68
+ specification_version: 2
69
+ summary: My extensions to core ruby classes, similar to activesupport and facets gems.
70
+ test_files: []
71
+