epitools 0.4.26 → 0.4.28
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/VERSION +1 -1
- data/epitools.gemspec +3 -2
- data/lib/epitools/basetypes.rb +54 -46
- data/lib/epitools/its.rb +48 -0
- data/lib/epitools/numwords.rb +22 -15
- data/spec/basetypes_spec.rb +38 -0
- metadata +3 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.28
|
data/epitools.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{epitools}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.28"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["epitron"]
|
12
|
-
s.date = %q{2011-04-
|
12
|
+
s.date = %q{2011-04-27}
|
13
13
|
s.description = %q{Miscellaneous utility libraries to make my life easier.}
|
14
14
|
s.email = %q{chris@ill-logic.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
"lib/epitools/clitools.rb",
|
32
32
|
"lib/epitools/colored.rb",
|
33
33
|
"lib/epitools/hexdump.rb",
|
34
|
+
"lib/epitools/its.rb",
|
34
35
|
"lib/epitools/lcs.rb",
|
35
36
|
"lib/epitools/metaclass.rb",
|
36
37
|
"lib/epitools/niceprint.rb",
|
data/lib/epitools/basetypes.rb
CHANGED
@@ -449,6 +449,21 @@ class Object
|
|
449
449
|
obj
|
450
450
|
end
|
451
451
|
|
452
|
+
|
453
|
+
#
|
454
|
+
# Return a copy of the class with modules mixed into it.
|
455
|
+
#
|
456
|
+
def self.using(*args)
|
457
|
+
if block_given?
|
458
|
+
yield using(*args)
|
459
|
+
else
|
460
|
+
copy = self.dup
|
461
|
+
args.each { |arg| copy.send(:include, arg) }
|
462
|
+
copy
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
|
452
467
|
#
|
453
468
|
# Instead of:
|
454
469
|
# if cookie_jar.include? cookie
|
@@ -502,6 +517,7 @@ class Object
|
|
502
517
|
end
|
503
518
|
|
504
519
|
|
520
|
+
|
505
521
|
class Hash
|
506
522
|
|
507
523
|
#
|
@@ -584,65 +600,57 @@ class Hash
|
|
584
600
|
def self.of_integers
|
585
601
|
new(0)
|
586
602
|
end
|
587
|
-
|
588
|
-
end
|
589
603
|
|
590
|
-
unless defined?(BasicObject)
|
591
604
|
#
|
592
|
-
#
|
605
|
+
# Makes each element in the `path` array point to a hash containing the next element in the `path`.
|
606
|
+
# Useful for turning a bunch of strings (paths, module names, etc.) into a tree.
|
593
607
|
#
|
594
|
-
|
595
|
-
|
608
|
+
# Example:
|
609
|
+
# h = {}
|
610
|
+
# h.mkdir_p(["a", "b", "c"]) #=> {"a"=>{"b"=>{"c"=>{}}}}
|
611
|
+
# h.mkdir_p(["a", "b", "whoa"]) #=> {"a"=>{"b"=>{"c"=>{}, "whoa"=>{}}}}
|
612
|
+
#
|
613
|
+
def mkdir_p(path)
|
614
|
+
return if path.empty?
|
615
|
+
dir = path.first
|
616
|
+
self[dir] ||= {}
|
617
|
+
self[dir].mkdir_p(path[1..-1])
|
618
|
+
self
|
596
619
|
end
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
module Kernel
|
601
|
-
|
602
|
-
protected
|
603
|
-
|
604
|
-
#
|
605
|
-
# Magic "its" Mapping
|
606
|
-
# -------------------
|
620
|
+
|
607
621
|
#
|
608
|
-
#
|
609
|
-
# User.find(:all).map{|x| x.contacts.map{|y| y.last_name.capitalize }}
|
622
|
+
# Turn some nested hashes into a tree (returns an array of strings, padded on the left with indents.)
|
610
623
|
#
|
611
|
-
|
612
|
-
|
624
|
+
def tree(level=0, indent=" ")
|
625
|
+
result = []
|
626
|
+
dent = indent * level
|
627
|
+
each do |key, val|
|
628
|
+
result << dent+key
|
629
|
+
result += val.tree(level+1) if val.any?
|
630
|
+
end
|
631
|
+
result
|
632
|
+
end
|
633
|
+
|
613
634
|
#
|
614
|
-
#
|
615
|
-
# User.find(:all).map &its.contacts.map(&its.last_name.capitalize)
|
635
|
+
# Print the result of `tree`
|
616
636
|
#
|
617
|
-
def
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
637
|
+
def print_tree
|
638
|
+
tree.each { |row| puts row }
|
639
|
+
nil
|
640
|
+
end
|
641
|
+
|
623
642
|
end
|
624
643
|
|
625
|
-
|
626
|
-
|
627
|
-
#
|
628
|
-
|
629
|
-
|
630
|
-
|
644
|
+
unless defined?(BasicObject)
|
645
|
+
#
|
646
|
+
# A BasicObject class for Ruby 1.8
|
647
|
+
#
|
648
|
+
class BasicObject
|
649
|
+
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
631
650
|
end
|
651
|
+
end
|
632
652
|
|
633
|
-
def method_missing(*args, &block)
|
634
|
-
@methods << [args, block] unless args == [:respond_to?, :to_proc]
|
635
|
-
self
|
636
|
-
end
|
637
653
|
|
638
|
-
def to_proc
|
639
|
-
lambda do |obj|
|
640
|
-
@methods.inject(obj) do |current,(args,block)|
|
641
|
-
current.send(*args, &block)
|
642
|
-
end
|
643
|
-
end
|
644
|
-
end
|
645
|
-
end
|
646
654
|
|
647
655
|
class NotWrapper < BasicObject # :nodoc:
|
648
656
|
def initialize(orig)
|
data/lib/epitools/its.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
module Kernel
|
3
|
+
|
4
|
+
protected
|
5
|
+
|
6
|
+
#
|
7
|
+
# Magic "its" Mapping
|
8
|
+
# -------------------
|
9
|
+
#
|
10
|
+
# The pure-Ruby way:
|
11
|
+
# User.find(:all).map{|x| x.contacts.map{|y| y.last_name.capitalize }}
|
12
|
+
#
|
13
|
+
# With Symbol#to_proc:
|
14
|
+
# User.find(:all).map{|x|x.contacts.map(&:last_name).map(&:capitalize)}
|
15
|
+
#
|
16
|
+
# Magic "its" way:
|
17
|
+
# User.find(:all).map &its.contacts.map(&its.last_name.capitalize)
|
18
|
+
#
|
19
|
+
def it()
|
20
|
+
It.new
|
21
|
+
end
|
22
|
+
|
23
|
+
alias its it
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
class It < BasicObject # :nodoc:
|
29
|
+
#undef_method( *(instance_methods - ["__id__", "__send__"]) )
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@methods = []
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(*args, &block)
|
36
|
+
@methods << [args, block] unless args == [:respond_to?, :to_proc]
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_proc
|
41
|
+
lambda do |obj|
|
42
|
+
@methods.inject(obj) do |current,(args,block)|
|
43
|
+
current.send(*args, &block)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
data/lib/epitools/numwords.rb
CHANGED
@@ -2,29 +2,43 @@ require 'epitools/basetypes'
|
|
2
2
|
require 'bigdecimal'
|
3
3
|
require 'set'
|
4
4
|
|
5
|
+
#
|
6
|
+
# Allow numbers to be converted into words, or exprssed more easily with words.
|
7
|
+
#
|
8
|
+
# Examples:
|
9
|
+
# >> 1.thousand
|
10
|
+
# => 1_000
|
11
|
+
|
12
|
+
# >> 1.27.million.billion
|
13
|
+
# => 1_270_000_000_000_000
|
14
|
+
#
|
15
|
+
# >> 12873218731.to_words
|
16
|
+
# => "twelve billion, eight-hundred and seventy-three million, two-hundred and eighteen thousand, seven-hundred and thirty-one"
|
17
|
+
#
|
18
|
+
# Works on numbers up to a googol!
|
19
|
+
#
|
5
20
|
class Numeric
|
6
21
|
|
22
|
+
# < 20
|
7
23
|
NAMES_SMALL = [
|
8
24
|
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
|
9
25
|
]
|
10
26
|
|
27
|
+
# 20-90
|
11
28
|
NAMES_MEDIUM = [
|
12
29
|
"twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"
|
13
30
|
]
|
14
31
|
|
32
|
+
# >= 100
|
15
33
|
NAMES_LARGE = [
|
16
34
|
"thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion", "undecillion", "duodecillion", "tredecillion", "quattuordecillion", "quindecillion", "sexdecillion", "septendecillion", "octodecillion", "novemdecillion", "vigintillion", "unvigintillion", "duovigintillion", "trevigintillion", "quattuorvigintillion", "quinvigintillion", "sexvigintillion", "septenvigintillion", "octovigintillion", "novemvigintillion", "trigintillion", "untrigintillion", "duotrigintillion"
|
17
35
|
]
|
18
36
|
|
19
|
-
NAMES_LARGE_LOOKUP = Set.new(NAMES_LARGE)
|
20
|
-
|
21
|
-
|
22
37
|
#
|
23
38
|
# Convert this number to words (eg: 69 => 'sixty-nine').
|
24
39
|
# Works with numbers up to a googol (10^100).
|
25
40
|
#
|
26
41
|
def to_words
|
27
|
-
|
28
42
|
if is_a? Integer
|
29
43
|
num = self
|
30
44
|
else
|
@@ -93,18 +107,13 @@ class Numeric
|
|
93
107
|
end
|
94
108
|
|
95
109
|
whole_thing.join ', '
|
96
|
-
|
97
110
|
end
|
98
|
-
|
111
|
+
|
99
112
|
#
|
100
|
-
#
|
101
|
-
# eg: 10.million #=> 10_000_000
|
113
|
+
# Define the .million, .thousand, .hundred, etc. methods.
|
102
114
|
#
|
103
|
-
|
104
|
-
|
105
|
-
rescue NoMethodError
|
106
|
-
if NAMES_LARGE_LOOKUP.include? meth.to_s
|
107
|
-
magnitude = NAMES_LARGE.index(meth.to_s)
|
115
|
+
NAMES_LARGE.each_with_index do |name, magnitude|
|
116
|
+
define_method name do
|
108
117
|
pow = (magnitude+1) * 3
|
109
118
|
factor = 10**pow
|
110
119
|
|
@@ -113,8 +122,6 @@ class Numeric
|
|
113
122
|
else
|
114
123
|
self * factor
|
115
124
|
end
|
116
|
-
else
|
117
|
-
raise NoMethodError.new(meth)
|
118
125
|
end
|
119
126
|
end
|
120
127
|
|
data/spec/basetypes_spec.rb
CHANGED
@@ -73,6 +73,32 @@ describe Object do
|
|
73
73
|
|
74
74
|
end
|
75
75
|
|
76
|
+
|
77
|
+
describe Class do
|
78
|
+
|
79
|
+
it "uses" do
|
80
|
+
module Test1
|
81
|
+
def test1; :test1; end
|
82
|
+
end
|
83
|
+
|
84
|
+
module Test2
|
85
|
+
def test2; :test2; end
|
86
|
+
end
|
87
|
+
|
88
|
+
Hash.using(Test1).new.test1.should == :test1
|
89
|
+
Hash.using(Test2).new.test2.should == :test2
|
90
|
+
h = Hash.using(Test1, Test2).new
|
91
|
+
h.test1.should == :test1
|
92
|
+
h.test2.should == :test2
|
93
|
+
|
94
|
+
Hash.using(Test1) do |h|
|
95
|
+
h.new.test1.should == :test1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
|
76
102
|
describe Numeric do
|
77
103
|
|
78
104
|
it "commatizes" do
|
@@ -85,6 +111,7 @@ describe Numeric do
|
|
85
111
|
|
86
112
|
end
|
87
113
|
|
114
|
+
|
88
115
|
describe String do
|
89
116
|
|
90
117
|
it "rot13s" do
|
@@ -95,6 +122,7 @@ describe String do
|
|
95
122
|
|
96
123
|
end
|
97
124
|
|
125
|
+
|
98
126
|
describe Integer do
|
99
127
|
|
100
128
|
it "integer?" do
|
@@ -242,6 +270,16 @@ describe Hash do
|
|
242
270
|
h.values.should == [1,1]
|
243
271
|
end
|
244
272
|
|
273
|
+
it "mkdir_p's and trees" do
|
274
|
+
h = {}
|
275
|
+
h.mkdir_p(["a", "b", "c"]).should == {"a"=>{"b"=>{"c"=>{}}}}
|
276
|
+
h.mkdir_p(["a", "b", "whoa"]).should == {"a"=>{"b"=>{"c"=>{}, "whoa"=>{}}}}
|
277
|
+
|
278
|
+
lambda {
|
279
|
+
h.tree.should == ["a", " b", " c", " whoa"]
|
280
|
+
}.should_not raise_error
|
281
|
+
end
|
282
|
+
|
245
283
|
end
|
246
284
|
|
247
285
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: epitools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.4.
|
5
|
+
version: 0.4.28
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- epitron
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-27 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- lib/epitools/clitools.rb
|
71
71
|
- lib/epitools/colored.rb
|
72
72
|
- lib/epitools/hexdump.rb
|
73
|
+
- lib/epitools/its.rb
|
73
74
|
- lib/epitools/lcs.rb
|
74
75
|
- lib/epitools/metaclass.rb
|
75
76
|
- lib/epitools/niceprint.rb
|