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 +3 -0
- data/README.txt +28 -0
- data/Rakefile +35 -0
- data/bin/libmatty +8 -0
- data/lib/libmatty.rb +49 -0
- data/lib/libmatty/array.rb +42 -0
- data/lib/libmatty/class.rb +167 -0
- data/lib/libmatty/dir.rb +23 -0
- data/lib/libmatty/duplicable.rb +39 -0
- data/lib/libmatty/enumerable.rb +16 -0
- data/lib/libmatty/file.rb +32 -0
- data/lib/libmatty/fixnum.rb +25 -0
- data/lib/libmatty/hash.rb +47 -0
- data/lib/libmatty/integer.rb +120 -0
- data/lib/libmatty/ipaddr.rb +113 -0
- data/lib/libmatty/irb.rb +29 -0
- data/lib/libmatty/math.rb +6 -0
- data/lib/libmatty/module.rb +67 -0
- data/lib/libmatty/numeric.rb +12 -0
- data/lib/libmatty/object.rb +33 -0
- data/lib/libmatty/range.rb +16 -0
- data/lib/libmatty/socket.rb +20 -0
- data/lib/libmatty/string.rb +450 -0
- data/lib/libmatty/symbol.rb +15 -0
- data/spec/libmatty_spec.rb +8 -0
- data/spec/spec_helper.rb +16 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/test_libmatty.rb +0 -0
- metadata +108 -0
data/History.txt
ADDED
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
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
|
data/lib/libmatty/dir.rb
ADDED
@@ -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
|