epitools 0.4.26 → 0.4.28
Sign up to get free protection for your applications and to get access to all the features.
- 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
|