tduehr-libmatty 0.9.0

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/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ == 0.9.0 / 2009-05-10
2
+
3
+ * initial github commit
data/README.txt ADDED
@@ -0,0 +1,28 @@
1
+ libmatty
2
+ by Matasano Security, LLC
3
+ http://matasano.com/log
4
+
5
+ == DESCRIPTION:
6
+
7
+ Standard Matasano ruby extensions library
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Every time we ask "Why isn't this in the standard library?" we add it to this.
12
+
13
+ == SYNOPSIS:
14
+
15
+ require 'libmatty' # load everything
16
+ require 'libmatty/string'
17
+
18
+ == REQUIREMENTS:
19
+
20
+ * most of the extensions have no requirements
21
+
22
+ * exceptions:
23
+ *
24
+
25
+ == INSTALL:
26
+
27
+ * sudo gem install libmatty
28
+
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ # Look in the tasks/setup.rb file for the various options that can be
2
+ # configured in this Rakefile. The .rake files in the tasks directory
3
+ # are where the options are used.
4
+
5
+ begin
6
+ require 'bones'
7
+ Bones.setup
8
+ rescue LoadError
9
+ begin
10
+ load 'tasks/setup.rb'
11
+ rescue LoadError
12
+ raise RuntimeError, '### please install the "bones" gem ###'
13
+ end
14
+ end
15
+
16
+ ensure_in_path 'lib'
17
+ require 'libmatty'
18
+
19
+ task :default => 'spec:run'
20
+
21
+ PROJ.name = 'libmatty'
22
+ PROJ.ignore_file = '.gitignore'
23
+ PROJ.authors = 'Matasano Security, LLC'
24
+ PROJ.email = 'td@matasano.com'
25
+ PROJ.description = 'Stanard Matasano extensions library for ruby'
26
+ PROJ.url = 'http://github.com/tduehr/libmatty/tree/master'
27
+ PROJ.version = Libmatty::VERSION
28
+ # PROJ.rubyforge.name = 'libmatty'
29
+
30
+ PROJ.spec.opts << '--color'
31
+
32
+ PROJ.rdoc.opts << '--inline-source'
33
+ PROJ.rdoc.opts << '--line-numbers'
34
+
35
+ # EOF
data/bin/libmatty ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(
4
+ File.join(File.dirname(__FILE__), %w[.. lib libmatty]))
5
+
6
+ # Put your code here
7
+
8
+ # EOF
data/lib/libmatty.rb ADDED
@@ -0,0 +1,49 @@
1
+
2
+ module Libmatty
3
+
4
+ # :stopdoc:
5
+ VERSION = '0.9.0'
6
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
+ # :startdoc:
9
+
10
+ # Returns the version string for the library.
11
+ #
12
+ def self.version
13
+ VERSION
14
+ end
15
+
16
+ # Returns the library path for the module. If any arguments are given,
17
+ # they will be joined to the end of the libray path using
18
+ # <tt>File.join</tt>.
19
+ #
20
+ def self.libpath( *args )
21
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
22
+ end
23
+
24
+ # Returns the lpath for the module. If any arguments are given,
25
+ # they will be joined to the end of the path using
26
+ # <tt>File.join</tt>.
27
+ #
28
+ def self.path( *args )
29
+ args.empty? ? PATH : ::File.join(PATH, args.flatten)
30
+ end
31
+
32
+ # Utility method used to require all files ending in .rb that lie in the
33
+ # directory below this file that has the same name as the filename passed
34
+ # in. Optionally, a specific _directory_ name can be passed in such that
35
+ # the _filename_ does not have to be equivalent to the directory.
36
+ #
37
+ def self.require_all_libs_relative_to( fname, dir = nil )
38
+ dir ||= ::File.basename(fname, '.*')
39
+ search_me = ::File.expand_path(
40
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
41
+
42
+ Dir.glob(search_me).sort.each {|rb| require rb}
43
+ end
44
+
45
+ end # module Libmatty
46
+
47
+ Libmatty.require_all_libs_relative_to(__FILE__)
48
+
49
+ # EOF
@@ -0,0 +1,42 @@
1
+ class Array
2
+ module ArrayExtensions
3
+ # Assume an array of key, value tuples, and convert to Hash
4
+ def to_hash
5
+ r = {}
6
+ each {|it| r[it[0]] = it[1]}
7
+ return r
8
+ end
9
+
10
+ def kind_of_these? y
11
+ inject(false) {|acc, klass| acc || y.kind_of?(klass)}
12
+ end
13
+
14
+ # return first hash-like element with key k
15
+ def kassoc(k)
16
+ each { |h| return h if h.try(:has_key?, k) }
17
+ return nil
18
+ end
19
+
20
+ # return first hash-like element with value v
21
+ def vassoc(v)
22
+ each { |h| return h if h.try(:has_value?, v) }
23
+ return nil
24
+ end
25
+
26
+ def extract_options!
27
+ last.is_a?(::Hash) ? pop : {}
28
+ end
29
+
30
+ def strip(*args)
31
+ list=[]
32
+
33
+ self.each_with_index do | e, i |
34
+ if(not args.member?(i))
35
+ list << e
36
+ end
37
+ end
38
+ return list
39
+ end
40
+ end
41
+ include ArrayExtensions
42
+ end
@@ -0,0 +1,167 @@
1
+ class Class
2
+ module ClassExtensions
3
+ # Also crazy that this isn't in the library
4
+ def inherits_from?(klass)
5
+ return true if self == klass
6
+ return true if self.superclass == klass
7
+ return false if self.superclass == Object
8
+
9
+ rec = lambda do |x|
10
+ if x == Object
11
+ false
12
+ elsif x == klass
13
+ true
14
+ else
15
+ rec.call(x.superclass)
16
+ end
17
+ end
18
+
19
+ rec.call(self)
20
+ end
21
+
22
+ def alias_cmethod(to, from)
23
+ (class << self;self;end).class_eval {
24
+ define_method to do |*args|
25
+ send(from, *args)
26
+ end
27
+ }
28
+ end
29
+
30
+
31
+ # Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
32
+ # their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
33
+ # to, for example, an array without those additions being shared with either their parent, siblings, or
34
+ # children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
35
+ def class_inheritable_reader(*syms)
36
+ syms.each do |sym|
37
+ next if sym.is_a?(Hash)
38
+ class_eval <<-EOS
39
+ def self.#{sym}
40
+ read_inheritable_attribute(:#{sym})
41
+ end
42
+
43
+ def #{sym}
44
+ self.class.#{sym}
45
+ end
46
+ EOS
47
+ end
48
+ end
49
+
50
+ def class_inheritable_writer(*syms)
51
+ options = syms.extract_options!
52
+ syms.each do |sym|
53
+ class_eval <<-EOS
54
+ def self.#{sym}=(obj)
55
+ write_inheritable_attribute(:#{sym}, obj)
56
+ end
57
+
58
+ #{"
59
+ def #{sym}=(obj)
60
+ self.class.#{sym} = obj
61
+ end
62
+ " unless options[:instance_writer] == false }
63
+ EOS
64
+ end
65
+ end
66
+
67
+ def class_inheritable_array_writer(*syms)
68
+ options = syms.extract_options!
69
+ syms.each do |sym|
70
+ class_eval <<-EOS
71
+ def self.#{sym}=(obj)
72
+ write_inheritable_array(:#{sym}, obj)
73
+ end
74
+
75
+ #{"
76
+ def #{sym}=(obj)
77
+ self.class.#{sym} = obj
78
+ end
79
+ " unless options[:instance_writer] == false }
80
+ EOS
81
+ end
82
+ end
83
+
84
+ def class_inheritable_hash_writer(*syms)
85
+ options = syms.extract_options!
86
+ syms.each do |sym|
87
+ class_eval <<-EOS
88
+ def self.#{sym}=(obj)
89
+ write_inheritable_hash(:#{sym}, obj)
90
+ end
91
+
92
+ #{"
93
+ def #{sym}=(obj)
94
+ self.class.#{sym} = obj
95
+ end
96
+ " unless options[:instance_writer] == false }
97
+ EOS
98
+ end
99
+ end
100
+
101
+ def class_inheritable_accessor(*syms)
102
+ class_inheritable_reader(*syms)
103
+ class_inheritable_writer(*syms)
104
+ end
105
+
106
+ def class_inheritable_array(*syms)
107
+ class_inheritable_reader(*syms)
108
+ class_inheritable_array_writer(*syms)
109
+ end
110
+
111
+ def class_inheritable_hash(*syms)
112
+ class_inheritable_reader(*syms)
113
+ class_inheritable_hash_writer(*syms)
114
+ end
115
+
116
+ def inheritable_attributes
117
+ @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
118
+ end
119
+
120
+ def write_inheritable_attribute(key, value)
121
+ if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
122
+ @inheritable_attributes = {}
123
+ end
124
+ inheritable_attributes[key] = value
125
+ end
126
+
127
+ def write_inheritable_array(key, elements)
128
+ write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
129
+ write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
130
+ end
131
+
132
+ def write_inheritable_hash(key, hash)
133
+ write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
134
+ write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
135
+ end
136
+
137
+ def read_inheritable_attribute(key)
138
+ inheritable_attributes[key]
139
+ end
140
+
141
+ def reset_inheritable_attributes
142
+ @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
143
+ end
144
+ private
145
+
146
+ # Prevent this constant from being created multiple times
147
+ EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES)
148
+
149
+ def inherited_with_inheritable_attributes(child)
150
+ inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
151
+
152
+ if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
153
+ new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
154
+ else
155
+ new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
156
+ memo.update(key => value.duplicable? ? value.dup : value)
157
+ end
158
+ end
159
+
160
+ child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
161
+ end
162
+ end
163
+
164
+ include ClassExtensions
165
+ alias inherited_without_inheritable_attributes inherited
166
+ alias inherited inherited_with_inheritable_attributes
167
+ end
@@ -0,0 +1,23 @@
1
+ class Dir
2
+ module DirExtensions
3
+ module ClassMethods
4
+ # as with shell pushd/popd
5
+ ##
6
+ def with_dir(d)
7
+ begin
8
+ o = Dir.getwd
9
+ Dir.chdir(d)
10
+ yield
11
+ rescue
12
+ raise
13
+ ensure
14
+ Dir.chdir(o)
15
+ end
16
+ end
17
+ end
18
+ def self.included(klass)
19
+ klass.extend ClassMethods
20
+ end
21
+ end
22
+ include DirExtensions
23
+ end
@@ -0,0 +1,39 @@
1
+ class Object
2
+ # Can you safely .dup this object?
3
+ # False for nil, false, true, symbols, and numbers; true otherwise.
4
+ # TODO: Should be done the other way around not all that will ever
5
+ # inherit from Object can be dupped
6
+ def duplicable?
7
+ true
8
+ end
9
+ end
10
+
11
+ class NilClass #:nodoc:
12
+ def duplicable?
13
+ false
14
+ end
15
+ end
16
+
17
+ class FalseClass #:nodoc:
18
+ def duplicable?
19
+ false
20
+ end
21
+ end
22
+
23
+ class TrueClass #:nodoc:
24
+ def duplicable?
25
+ false
26
+ end
27
+ end
28
+
29
+ class Symbol #:nodoc:
30
+ def duplicable?
31
+ false
32
+ end
33
+ end
34
+
35
+ class Numeric #:nodoc:
36
+ def duplicable?
37
+ false
38
+ end
39
+ end
@@ -0,0 +1,16 @@
1
+ module Enumerable
2
+ module EnumerableExtensions
3
+ def each_recursive(&block)
4
+ self.each do |n|
5
+ block.call(n)
6
+ n.each_recursive(&block) if n.kind_of? Array or n.kind_of? Hash
7
+ end
8
+ end
9
+
10
+ # return a random selection from any list of anything XXX
11
+ def choice
12
+ rand
13
+ end
14
+ end
15
+ include EnumerableExtensions
16
+ end
@@ -0,0 +1,32 @@
1
+ class File
2
+ module FileExtensions
3
+ module ClassMethods
4
+ def mkfifo(name, mode="666", open_mode="r")
5
+ if File.exists? name and File.pipe? name # Leftover from before
6
+ File.delete name
7
+ end
8
+
9
+ # apalling, but ruby/dl has x-p problems
10
+ if ! File.exists? name
11
+ `mkfifo -m #{ mode } #{ name }`
12
+ end
13
+
14
+ return File.open(name, open_mode)
15
+ end
16
+
17
+ # returns the contents of a file
18
+ def slurp(fn)
19
+ ret = nil
20
+ File.open(fn, "r") do |f|
21
+ ret = f.read()
22
+ end
23
+ return ret
24
+ end
25
+ end
26
+
27
+ def self.included(klass)
28
+ klass.extend(ClassMethods)
29
+ end
30
+ end
31
+ include FileExtensions
32
+ end