tduehr-libmatty 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|