quality_extensions 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/quality_extensions/color/gradiate.rb +72 -33
- data/lib/quality_extensions/color/rgb.rb +101 -8
- data/lib/quality_extensions/console/command.rb +2 -2
- data/lib/quality_extensions/enumerable/every.rb +72 -0
- data/lib/quality_extensions/fixnum/change_base.rb +107 -0
- data/lib/quality_extensions/hash/except.rb +3 -0
- data/lib/quality_extensions/hash/only.rb +64 -7
- data/lib/quality_extensions/module/initializer.rb +1 -1
- data/lib/quality_extensions/numeric/diff.rb +42 -0
- data/lib/quality_extensions/pathname.rb +128 -0
- data/lib/quality_extensions/template.rb +1 -1
- metadata +7 -3
- data/lib/quality_extensions/enumerable/enum.rb +0 -69
@@ -1,31 +1,37 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#--
|
2
|
+
# Source: http://tfletcher.com/lib/gradiate.rb
|
3
|
+
# Author:: Tim Fletcher
|
4
|
+
# Copyright:: Copyright (c) 2008, Tim Fletcher
|
5
|
+
# License:: Ruby License?
|
6
|
+
# Submit to Facets?:: No
|
7
|
+
# Developer notes::
|
8
|
+
# Changes::
|
9
|
+
#++
|
3
10
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
11
|
+
require 'facets/kernel/require_local'
|
12
|
+
require_local 'rgb'
|
13
|
+
require_local '../numeric/diff'
|
14
|
+
require_local '../enumerable/every'
|
9
15
|
|
10
16
|
module Enumerable
|
11
17
|
|
12
|
-
# Sorts objects in the enumeration and applies a
|
18
|
+
# Sorts objects in the enumeration and applies a color scale to them.
|
13
19
|
#
|
14
|
-
#
|
20
|
+
# Color ranges must be in the form [x, y], where x and y are either fixnums
|
15
21
|
# (e.g. 255, 0xFF) or hexadecimal strings (e.g. 'FF').
|
16
22
|
#
|
17
|
-
# Ranges can be provided for each RGB
|
23
|
+
# Ranges can be provided for each RGB color e.g.
|
18
24
|
#
|
19
25
|
# gradiate(:red => red_range)
|
20
26
|
#
|
21
|
-
# ...and a default range (for all
|
27
|
+
# ...and a default range (for all colors) can be set using :all e.g.
|
22
28
|
#
|
23
29
|
# gradiate(:all => default_range, :green => green_range)
|
24
30
|
#
|
25
|
-
# If no
|
31
|
+
# If no color ranges are supplied then the _sorted_ enumeration will be returned.
|
26
32
|
#
|
27
|
-
# Objects contained in the enumeration are expected to have a
|
28
|
-
# attribute/method that returns a <tt>
|
33
|
+
# Objects contained in the enumeration are expected to have a color (or colour)
|
34
|
+
# attribute/method that returns a <tt>Color::RGB</tt> object (or similar).
|
29
35
|
#
|
30
36
|
# By default, objects are sorted using <tt>:to_i</tt>. This can be overidden
|
31
37
|
# by setting <tt>options[:compare_using]</tt> to a different method symbol.
|
@@ -42,31 +48,64 @@ module Enumerable
|
|
42
48
|
next (a..b).every(c)
|
43
49
|
else [] end
|
44
50
|
end
|
51
|
+
|
45
52
|
objects = sort_by { |object| object.send(options[:compare_using] || :to_i) }
|
46
53
|
objects = objects.reverse if [:desc, :reverse].include?(options[:order])
|
47
54
|
objects.zip(*ranges).collect do |object, red, green, blue|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
55
|
+
color = object.respond_to?(:colour) ? object.colour : object.color
|
56
|
+
color.red = red if red
|
57
|
+
color.green = green if green
|
58
|
+
color.blue = blue if blue
|
52
59
|
next object
|
53
60
|
end
|
54
61
|
end
|
62
|
+
|
63
|
+
end
|
55
64
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
return block_given?? nil : result
|
65
|
+
# _____ _
|
66
|
+
# |_ _|__ ___| |_
|
67
|
+
# | |/ _ \/ __| __|
|
68
|
+
# | | __/\__ \ |_
|
69
|
+
# |_|\___||___/\__|
|
70
|
+
#
|
71
|
+
=begin test
|
72
|
+
require 'spec'
|
73
|
+
Spec::Runner.options.colour = true
|
74
|
+
ENV['AUTOTEST'] = '1'
|
75
|
+
|
76
|
+
describe Enumerable.instance_method(:gradiate) do
|
77
|
+
class Thing < ::Struct.new(:name, :color)
|
70
78
|
end
|
71
|
-
|
79
|
+
|
80
|
+
it "works when gradiating from 'cc' to 'dd' for all components" do
|
81
|
+
results = [
|
82
|
+
Thing.new('d', Color::RGB.new( 0, 0, 0)),
|
83
|
+
Thing.new('c', Color::RGB.new( 0, 0, 0)),
|
84
|
+
Thing.new('b', Color::RGB.new( 0, 0, 0)),
|
85
|
+
Thing.new('a', Color::RGB.new( 0, 0, 0)),
|
86
|
+
].gradiate :all => ['cc', 'dd'], :compare_using => :name
|
87
|
+
|
88
|
+
results.map(&:name).should == %w[a b c d]
|
89
|
+
|
90
|
+
results.map(&:color)[0].should == Color::RGB.new(0xcccccc)
|
91
|
+
results.map(&:color)[1].should == Color::RGB.new(0xd1d1d1)
|
92
|
+
results.map(&:color)[2].should == Color::RGB.new(0xd6d6d6)
|
93
|
+
results.map(&:color)[3].should == Color::RGB.new(0xdbdbdb)
|
94
|
+
|
95
|
+
results.map(&:color).map(&:red).enum_cons(2).map {|a,b| b-a}.map {|a| a == 5}.should be_all
|
96
|
+
end
|
97
|
+
|
98
|
+
it "works when gradiating from '00' to 'ff' for red component" do
|
99
|
+
results = [
|
100
|
+
Thing.new('ruby', Color::RGB.new(255, 0, 0)),
|
101
|
+
Thing.new('apple', Color::RGB.new( 0,255, 0)),
|
102
|
+
Thing.new('blueberry', Color::RGB.new( 0, 0,255)),
|
103
|
+
].gradiate :red => ['00', 'ff'], :compare_using => :name
|
104
|
+
|
105
|
+
results.map(&:color)[0].should == Color::RGB.new(0x00ff00)
|
106
|
+
results.map(&:color)[1].should == Color::RGB.new(0x7f00ff)
|
107
|
+
results.map(&:color)[2].should == Color::RGB.new(0xfe0000)
|
108
|
+
end
|
109
|
+
|
72
110
|
end
|
111
|
+
=end
|
@@ -1,9 +1,21 @@
|
|
1
|
-
|
1
|
+
#--
|
2
|
+
# Source: http://tfletcher.com/lib/rgb.rb
|
3
|
+
# Author:: Tim Fletcher
|
4
|
+
# Copyright:: Copyright (c) 2008, Tim Fletcher
|
5
|
+
# License:: Ruby License?
|
6
|
+
# Submit to Facets?:: Maybe
|
7
|
+
# Developer notes::
|
8
|
+
# Changes::
|
9
|
+
# * 2009-01-11 (Tyler):
|
10
|
+
# * Added RGB#to_i, #inspect, #==
|
11
|
+
# * Added some tests
|
12
|
+
#++
|
2
13
|
|
3
14
|
class Fixnum # :nodoc:
|
4
15
|
def to_rgb
|
5
16
|
a, b = divmod(65536)
|
6
|
-
|
17
|
+
b, c = b.divmod(256)
|
18
|
+
return [a, b, c]
|
7
19
|
end
|
8
20
|
end
|
9
21
|
|
@@ -19,11 +31,11 @@ class Symbol # :nodoc:
|
|
19
31
|
end
|
20
32
|
end
|
21
33
|
|
22
|
-
module
|
34
|
+
module Color # :nodoc:
|
23
35
|
#
|
24
36
|
# A lightweight implementation of rgb/hex colors, designed for web use.
|
25
37
|
#
|
26
|
-
# c =
|
38
|
+
# c = Color::RGB.new(0xFFFFFF)
|
27
39
|
#
|
28
40
|
# c.to_s -> "ffffff"
|
29
41
|
#
|
@@ -45,7 +57,7 @@ module Colour # :nodoc:
|
|
45
57
|
|
46
58
|
attr_reader :red, :green, :blue
|
47
59
|
|
48
|
-
# The following are the same
|
60
|
+
# The following are the same color:
|
49
61
|
#
|
50
62
|
# RGB.new(0xFFFFFF)
|
51
63
|
# RGB.new(:FFFFFF)
|
@@ -58,7 +70,7 @@ module Colour # :nodoc:
|
|
58
70
|
end
|
59
71
|
end
|
60
72
|
|
61
|
-
# Returns the hexadecimal string representation of the
|
73
|
+
# Returns the hexadecimal string representation of the color, f.e.:
|
62
74
|
#
|
63
75
|
# RGB.new(255, 255, 255).to_s -> "FFFFFF"
|
64
76
|
#
|
@@ -66,15 +78,96 @@ module Colour # :nodoc:
|
|
66
78
|
"%02x%02x%02x" % [ red, green, blue ]
|
67
79
|
end
|
68
80
|
|
81
|
+
def inspect
|
82
|
+
"<Color::RGB '#{to_s}'>"
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns the integral representation of the color, f.e.:
|
86
|
+
#
|
87
|
+
# RGB.new(255, 255, 255).to_i -> "FFFFFF"
|
88
|
+
#
|
89
|
+
def to_i
|
90
|
+
red*65536 + green*256 + blue
|
91
|
+
end
|
92
|
+
|
93
|
+
def ==(other)
|
94
|
+
to_s == other.to_s
|
95
|
+
end
|
96
|
+
|
69
97
|
protected
|
70
98
|
|
71
|
-
def set!(
|
99
|
+
def set!(color, value)
|
72
100
|
value = value.hex if value.respond_to?(:hex)
|
73
101
|
unless (0..255) === value
|
74
102
|
raise ArgumentError, "#{value.inspect} not in range 0..255"
|
75
103
|
end
|
76
|
-
instance_variable_set(:"@#{
|
104
|
+
instance_variable_set(:"@#{color}", value)
|
77
105
|
end
|
78
106
|
|
79
107
|
end
|
80
108
|
end
|
109
|
+
|
110
|
+
# _____ _
|
111
|
+
# |_ _|__ ___| |_
|
112
|
+
# | |/ _ \/ __| __|
|
113
|
+
# | | __/\__ \ |_
|
114
|
+
# |_|\___||___/\__|
|
115
|
+
#
|
116
|
+
=begin test
|
117
|
+
require 'spec'
|
118
|
+
Spec::Runner.options.colour = true
|
119
|
+
ENV['AUTOTEST'] = '1'
|
120
|
+
|
121
|
+
describe 'Fixnum#to_rgb' do
|
122
|
+
it do
|
123
|
+
(1).to_rgb. should == [0,0,1]
|
124
|
+
(65536*2).to_rgb. should == [2,0,0]
|
125
|
+
(65536*2 + 256*3 + 4).to_rgb. should == [2,3,4]
|
126
|
+
(65536*204 + 256*221 + 255).to_rgb.should == [204,221,255]
|
127
|
+
16777215.to_rgb. should == [255,255,255]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe 'String#to_rgb' do
|
132
|
+
it do
|
133
|
+
('000001').to_rgb.should == [0,0,1]
|
134
|
+
('020000').to_rgb.should == [2,0,0]
|
135
|
+
('020304').to_rgb.should == [2,3,4]
|
136
|
+
('ccddff').to_rgb.should == [204,221,255]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe 'Symbol#to_rgb' do
|
141
|
+
it do
|
142
|
+
(:'000001').to_rgb.should == [0,0,1]
|
143
|
+
(:'020000').to_rgb.should == [2,0,0]
|
144
|
+
(:'020304').to_rgb.should == [2,3,4]
|
145
|
+
(:ccddff). to_rgb.should == [204,221,255]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe Color::RGB do
|
150
|
+
it "equality" do
|
151
|
+
color = Color::RGB.new(0xFFFFFF)
|
152
|
+
Color::RGB.new(:FFFFFF). should == color
|
153
|
+
Color::RGB.new("FFFFFF"). should == color
|
154
|
+
Color::RGB.new(255, "FF", 0xFF).should == color
|
155
|
+
end
|
156
|
+
|
157
|
+
it "to_i" do
|
158
|
+
Color::RGB.new(0x000000).to_i.should == 0
|
159
|
+
Color::RGB.new(0x000100).to_i.should == 256
|
160
|
+
Color::RGB.new(0xFFFFFF).to_i.should == 16777215
|
161
|
+
end
|
162
|
+
|
163
|
+
it "to_s" do
|
164
|
+
Color::RGB.new(0x000000).to_s.should == '000000'
|
165
|
+
Color::RGB.new(0x000100).to_s.should == '000100'
|
166
|
+
Color::RGB.new(0xFFFFFF).to_s.should == 'ffffff'
|
167
|
+
end
|
168
|
+
|
169
|
+
it "inspect" do
|
170
|
+
Color::RGB.new(0x000000).inspect.should == "<Color::RGB '000000'>"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
=end
|
@@ -32,7 +32,7 @@
|
|
32
32
|
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
33
33
|
require 'shellwords'
|
34
34
|
require 'rubygems'
|
35
|
-
require 'facets/string/
|
35
|
+
require 'facets/string/modulize'
|
36
36
|
require 'escape' # http://www.a-k-r.org/escape/
|
37
37
|
|
38
38
|
# TODO Test
|
@@ -397,7 +397,7 @@ class Console::Command
|
|
397
397
|
|
398
398
|
# Extend subcommand option module
|
399
399
|
#subconst = subcommand.gsub(/\W/,'_').capitalize
|
400
|
-
subconst = @subcommand.
|
400
|
+
subconst = @subcommand.modulize
|
401
401
|
#p self.class.constants if $debug
|
402
402
|
if self.class.const_defined?(subconst)
|
403
403
|
puts "Extending self (#{self.class}) with subcommand module #{subconst}" if $debug
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#--
|
2
|
+
# Source: http://tfletcher.com/lib/gradiate.rb
|
3
|
+
# Author:: Tim Fletcher
|
4
|
+
# Copyright:: Copyright (c) 2008, Tim Fletcher
|
5
|
+
# License:: Ruby License?
|
6
|
+
# Submit to Facets?:: Yes
|
7
|
+
# Developer notes::
|
8
|
+
# Changes::
|
9
|
+
# * 2009-01-11 (Tyler):
|
10
|
+
# * Added some tests
|
11
|
+
#++
|
12
|
+
|
13
|
+
module Enumerable
|
14
|
+
|
15
|
+
# Yields every nth object (if invoked with a block),
|
16
|
+
# or returns an array of every nth object.
|
17
|
+
#
|
18
|
+
# every(2), for example, would return every other element from the enumerable:
|
19
|
+
#
|
20
|
+
# [1, 2, 3, 4, 5, 6].every(2) -> [1, 3, 5]
|
21
|
+
# [1, 2, 3, 4, 5, 6].every(2) { |i| ... } -> nil
|
22
|
+
#
|
23
|
+
def every(n)
|
24
|
+
result = [] unless block_given?
|
25
|
+
each_with_index do |object, i|
|
26
|
+
if i % n == 0
|
27
|
+
block_given?? yield(object) : result << object
|
28
|
+
end
|
29
|
+
end
|
30
|
+
return block_given?? nil : result
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# _____ _
|
36
|
+
# |_ _|__ ___| |_
|
37
|
+
# | |/ _ \/ __| __|
|
38
|
+
# | | __/\__ \ |_
|
39
|
+
# |_|\___||___/\__|
|
40
|
+
#
|
41
|
+
=begin test
|
42
|
+
require 'spec'
|
43
|
+
require 'facets/kernel/require_local'
|
44
|
+
require_local 'enum'
|
45
|
+
|
46
|
+
describe Enumerable.instance_method(:every) do
|
47
|
+
it "without block, every(1)" do
|
48
|
+
(1..6).every(1).should == (1..6).to_a
|
49
|
+
[1, 2].every(1).should == [1, 2]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "without block, every(2)" do
|
53
|
+
(1..6).every(2).should == [1, 3, 5]
|
54
|
+
[1, 2].every(2).should == [1]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "without block, every(3)" do
|
58
|
+
(1..7).every(3).should == [1, 4, 7]
|
59
|
+
(0..7).every(3).should == [0, 3, 6]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "with block, every(2)" do
|
63
|
+
results = []
|
64
|
+
(1..6).every(2) {|i| results << i.to_s}
|
65
|
+
results.should == %w[1 3 5]
|
66
|
+
end
|
67
|
+
|
68
|
+
it "as Enumerator" do
|
69
|
+
(1..6).enum(:every, 2).map(&:to_s).should == %w[1 3 5]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
=end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Maybe
|
6
|
+
# Developer notes:: It's probably already been implemented in a better, more efficient way. Will remove when I run across said better implementation...
|
7
|
+
# Changes::
|
8
|
+
#++
|
9
|
+
|
10
|
+
class Fixnum # :nodoc:
|
11
|
+
# Converts to a new base, returning the digits as an array.
|
12
|
+
def digits_for_new_base(base, padding = 0)
|
13
|
+
digits = []
|
14
|
+
if self == 0
|
15
|
+
digits = [0]
|
16
|
+
else
|
17
|
+
remainder = self
|
18
|
+
max_exponent = (Math.log(self)/Math.log(base)).to_i
|
19
|
+
max_exponent.downto(0) do |exp|
|
20
|
+
#puts "#{remainder} / #{base**exp}"
|
21
|
+
digit, remainder = remainder.divmod(base**exp)
|
22
|
+
digits << digit
|
23
|
+
end
|
24
|
+
end
|
25
|
+
digits.pad(-padding, 0)
|
26
|
+
end
|
27
|
+
|
28
|
+
def change_base(base, padding = 0, numerals = nil)
|
29
|
+
numerals ||= (0..9).to_a + ('a'..'z').to_a
|
30
|
+
numerals.map!(&:to_s)
|
31
|
+
|
32
|
+
digits_for_new_base(base, padding).map {|digit| numerals[digit]}.join
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# _____ _
|
37
|
+
# |_ _|__ ___| |_
|
38
|
+
# | |/ _ \/ __| __|
|
39
|
+
# | | __/\__ \ |_
|
40
|
+
# |_|\___||___/\__|
|
41
|
+
#
|
42
|
+
=begin test
|
43
|
+
require 'spec'
|
44
|
+
require 'facets/array/pad'
|
45
|
+
|
46
|
+
describe 'Fixnum#digits_for_new_base' do
|
47
|
+
it "8" do
|
48
|
+
8.digits_for_new_base( 2).should == [1, 0, 0, 0]
|
49
|
+
8.digits_for_new_base( 8).should == [ 1, 0]
|
50
|
+
8.digits_for_new_base(10).should == [ 8]
|
51
|
+
8.digits_for_new_base(16).should == [ 8]
|
52
|
+
end
|
53
|
+
|
54
|
+
it do
|
55
|
+
(1). digits_for_new_base(256, 3).should == [0,0,1]
|
56
|
+
(65536*204 + 256*221 + 255).digits_for_new_base(256, 3).should == [204,221,255]
|
57
|
+
16777215. digits_for_new_base(256, 3).should == [255,255,255]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'Fixnum#change_base' do
|
62
|
+
it "0" do
|
63
|
+
0.change_base(2).should == "0"
|
64
|
+
end
|
65
|
+
|
66
|
+
it "8" do
|
67
|
+
8.change_base( 2).should == "1000"
|
68
|
+
8.change_base( 8).should == "10"
|
69
|
+
8.change_base(10).should == "8"
|
70
|
+
8.change_base(16).should == "8"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "8, padded" do
|
74
|
+
8.change_base( 2, 5).should == "01000"
|
75
|
+
8.change_base( 8, 5).should == "00010"
|
76
|
+
8.change_base(10, 5).should == "00008"
|
77
|
+
8.change_base(16, 5).should == "00008"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "uses numerals above 9" do
|
81
|
+
10.change_base(16).should == "a"
|
82
|
+
11.change_base(16).should == "b"
|
83
|
+
12.change_base(16).should == "c"
|
84
|
+
13.change_base(16).should == "d"
|
85
|
+
14.change_base(16).should == "e"
|
86
|
+
15.change_base(16).should == "f"
|
87
|
+
# ...
|
88
|
+
35.change_base(36).should == "z"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "17" do
|
92
|
+
17.change_base( 2).should == "10001"
|
93
|
+
17.change_base( 8).should == "21"
|
94
|
+
17.change_base(10).should == "17"
|
95
|
+
17.change_base(16).should == "11"
|
96
|
+
end
|
97
|
+
|
98
|
+
it "lets you use custom numerals" do
|
99
|
+
custom_numerals = %w[) ! @ # $ % ^ & * (]
|
100
|
+
0.change_base(16, 0, custom_numerals).should == ")"
|
101
|
+
1.change_base(16, 0, custom_numerals).should == "!"
|
102
|
+
2.change_base(16, 0, custom_numerals).should == "@"
|
103
|
+
3.change_base(16, 0, custom_numerals).should == "#"
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
=end
|
@@ -1,19 +1,76 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
1
|
+
#--
|
2
|
+
# Source: http://pastie.org/10707 (08/29/2006 by lukeredpath)
|
3
|
+
# Author:: Unknown, Tyler Rick
|
4
|
+
# Copyright:: Unknown, Tyler Rick
|
5
|
+
# License:: Original: assumed public domain / Modified version: Ruby License
|
6
|
+
# Submit to Facets?:: No. Already in Facets (different implementation).
|
7
|
+
# Developer notes::
|
8
|
+
# Changes::
|
9
|
+
#++
|
4
10
|
|
5
11
|
class Hash
|
6
|
-
#
|
12
|
+
# Returns the hash with the keys named by +keys+ having been removed.
|
13
|
+
#
|
14
|
+
# {:a => 1, :b => 2, :c => 3}.except(:a)
|
15
|
+
# => {:b => 2, :c => 3}
|
7
16
|
def except(*keys)
|
8
17
|
self.reject { |k,v|
|
9
|
-
keys.include? k
|
18
|
+
keys.include? k
|
10
19
|
}
|
11
20
|
end
|
12
21
|
|
13
|
-
#
|
22
|
+
# Returns the hash with only the keys named by +keys+ having been kept.
|
23
|
+
#
|
24
|
+
# {:a => 1, :b => 2, :c => 3}.only(:a)
|
25
|
+
# => {:a => 1}
|
14
26
|
def only(*keys)
|
15
27
|
self.dup.reject { |k,v|
|
16
|
-
!keys.include? k
|
28
|
+
!keys.include? k
|
17
29
|
}
|
18
30
|
end
|
19
31
|
end
|
32
|
+
|
33
|
+
# _____ _
|
34
|
+
# |_ _|__ ___| |_
|
35
|
+
# | |/ _ \/ __| __|
|
36
|
+
# | | __/\__ \ |_
|
37
|
+
# |_|\___||___/\__|
|
38
|
+
#
|
39
|
+
=begin test
|
40
|
+
require 'test/unit'
|
41
|
+
require 'facets/hash/rekey'
|
42
|
+
|
43
|
+
class TheTest < Test::Unit::TestCase
|
44
|
+
def test_except
|
45
|
+
assert_equal({ :b => 2, :c => 3},
|
46
|
+
{:a => 1, :b => 2, :c => 3}.except(:a))
|
47
|
+
|
48
|
+
assert_equal({ :c => 3},
|
49
|
+
{:a => 1, :b => 2, :c => 3}.except(:a, :b))
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_except_does_not_symbolize_keys
|
53
|
+
assert_equal({ :a => 1, :b => 2},
|
54
|
+
{ :a => 1, :b => 2}.except('a'))
|
55
|
+
assert_equal({'a' => 1, 'b' => 2},
|
56
|
+
{'a' => 1, 'b' => 2}.except(:a))
|
57
|
+
|
58
|
+
# But it's easy to do if you need the hash rekeyed:
|
59
|
+
assert_equal({ 'b' => 2},
|
60
|
+
{:a => 1, :b => 2}.rekey(&:to_s).except('a'))
|
61
|
+
assert_equal({ :b => 2},
|
62
|
+
{'a' => 1, 'b' => 2}.rekey(&:to_sym).except(:a))
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def test_only
|
67
|
+
assert_equal({ :b => 2, :c => 3},
|
68
|
+
{:a => 1, :b => 2, :c => 3}.only(:b, :c))
|
69
|
+
|
70
|
+
assert_equal({ :c => 3},
|
71
|
+
{:a => 1, :b => 2, :c => 3}.only(:c))
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
=end
|
76
|
+
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# Author:: Trans?
|
3
3
|
# Copyright:: Copyright (c) Trans?
|
4
4
|
# License:: Ruby License
|
5
|
-
# Submit to Facets?:: No.
|
5
|
+
# Submit to Facets?:: No. Was removed from Facets in (or before) 2.4.1, though I'm not sure why. Salvaged from facets-1.8.54/lib/facets/core/module/initializer.rb.
|
6
6
|
# Developer notes::
|
7
7
|
#++
|
8
8
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#--
|
2
|
+
# Source: http://tfletcher.com/lib/gradiate.rb
|
3
|
+
# Author:: Tim Fletcher
|
4
|
+
# Copyright:: Copyright (c) 2008, Tim Fletcher
|
5
|
+
# License:: Ruby License?
|
6
|
+
# Submit to Facets?:: Yes
|
7
|
+
# Developer notes::
|
8
|
+
# Changes::
|
9
|
+
#++
|
10
|
+
|
11
|
+
class Numeric #:nodoc:
|
12
|
+
def diff(n)
|
13
|
+
return (self > n ? self - n : n - self)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# _____ _
|
18
|
+
# |_ _|__ ___| |_
|
19
|
+
# | |/ _ \/ __| __|
|
20
|
+
# | | __/\__ \ |_
|
21
|
+
# |_|\___||___/\__|
|
22
|
+
#
|
23
|
+
=begin test
|
24
|
+
require 'spec'
|
25
|
+
|
26
|
+
describe Numeric.instance_method(:diff) do
|
27
|
+
it "should not matter which object is the receiver" do
|
28
|
+
1.diff(3).should == 2
|
29
|
+
3.diff(1).should == 2
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be the same as taking the absolute value of the difference" do
|
33
|
+
1.diff(1).should == (1 - 1).abs
|
34
|
+
|
35
|
+
1.diff(3).should == (1 - 3).abs
|
36
|
+
3.diff(1).should == (3 - 1).abs
|
37
|
+
|
38
|
+
1. diff(-1).should == (1 - -1).abs
|
39
|
+
-1.diff(1). should == (-1 - 1).abs
|
40
|
+
end
|
41
|
+
end
|
42
|
+
=end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#--
|
3
|
+
# Author:: Tyler Rick
|
4
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
5
|
+
# License:: Ruby License
|
6
|
+
# Submit to Facets?::
|
7
|
+
# Developer notes:: Make a patch to actual pathname source.
|
8
|
+
# Changes::
|
9
|
+
#++
|
10
|
+
|
11
|
+
require 'pathname'
|
12
|
+
require 'tempfile'
|
13
|
+
|
14
|
+
class Pathname
|
15
|
+
# Creates a new temp file using Tempfile.new and returns the Pathname object for that file
|
16
|
+
def self.tempfile
|
17
|
+
Pathname.new(Tempfile.new('Pathname').path)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Moves self to +new_path+ using FileUtils.mv.
|
21
|
+
#
|
22
|
+
# See documentation for FileUtils.mv for a list of valid +options+.
|
23
|
+
#
|
24
|
+
# Returns Pathname object for +new_file+ file.
|
25
|
+
#
|
26
|
+
def mv(new_path, options = {})
|
27
|
+
FileUtils.mv self.to_s, new_path.to_s, options
|
28
|
+
Pathname.new(new_path)
|
29
|
+
end
|
30
|
+
alias_method :move, :mv
|
31
|
+
|
32
|
+
# Copies self to +new_path+ using FileUtils.cp.
|
33
|
+
#
|
34
|
+
# See documentation for FileUtils.cp for a list of valid +options+.
|
35
|
+
#
|
36
|
+
# Returns Pathname object for +new_file+ file.
|
37
|
+
#
|
38
|
+
def cp(new_path, options = {})
|
39
|
+
FileUtils.cp self.to_s, new_path.to_s, options
|
40
|
+
Pathname.new(new_path)
|
41
|
+
end
|
42
|
+
alias_method :copy, :cp
|
43
|
+
|
44
|
+
|
45
|
+
# Copies/install self to +dest+ using FileUtils.install.
|
46
|
+
#
|
47
|
+
# If src is not same as dest, copies it and changes the permission mode to mode. If dest is a directory, destination is dest/src.
|
48
|
+
#
|
49
|
+
# FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
|
50
|
+
# FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true
|
51
|
+
#
|
52
|
+
# Returns Pathname object for +dest+ file.
|
53
|
+
#
|
54
|
+
def install(dest, options = {})
|
55
|
+
FileUtils.install self.to_s, dest.to_s, options
|
56
|
+
Pathname.new(dest)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
# _____ _
|
68
|
+
# |_ _|__ ___| |_
|
69
|
+
# | |/ _ \/ __| __|
|
70
|
+
# | | __/\__ \ |_
|
71
|
+
# |_|\___||___/\__|
|
72
|
+
#
|
73
|
+
=begin test
|
74
|
+
require 'test/unit'
|
75
|
+
|
76
|
+
class TheTest < Test::Unit::TestCase
|
77
|
+
def setup
|
78
|
+
@object = Pathname.tempfile
|
79
|
+
|
80
|
+
new_file = Pathname.new('/tmp/Pathname_new_file')
|
81
|
+
new_file.unlink rescue nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_tempfile_actually_creates_file
|
85
|
+
assert @object.exist?
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_tempfile_has_path_in_tmp
|
89
|
+
assert_match %r(/tmp/Pathname), @object.to_s
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_mv_actually_moves_file(new_file = '/tmp/Pathname_new_file', options = {})
|
93
|
+
new_object = @object.mv(new_file, options)
|
94
|
+
assert !@object.exist?
|
95
|
+
assert new_object.exist?
|
96
|
+
assert_match %r(/tmp/Pathname), new_object.to_s
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_mv_also_accepts_Pathname
|
100
|
+
new_file = Pathname.new('/tmp/Pathname_new_file')
|
101
|
+
new_file.unlink rescue nil
|
102
|
+
assert !new_file.exist?
|
103
|
+
test_mv_actually_moves_file new_file
|
104
|
+
assert new_file.exist?
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_mv_accepts_noop_option
|
108
|
+
new_object = @object.mv('/tmp/Pathname_new_file', :noop => true)
|
109
|
+
assert @object.exist?
|
110
|
+
assert !new_object.exist?
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_cp_actually_copies_file
|
114
|
+
new_object = @object.cp('/tmp/Pathname_new_file')
|
115
|
+
assert @object.exist?
|
116
|
+
assert new_object.exist?
|
117
|
+
assert_match %r(/tmp/Pathname), new_object.to_s
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_install_actually_copies_file
|
121
|
+
new_object = @object.install('/tmp/Pathname_new_file')
|
122
|
+
assert @object.exist?
|
123
|
+
assert new_object.exist?
|
124
|
+
assert_match %r(/tmp/Pathname), new_object.to_s
|
125
|
+
end
|
126
|
+
end
|
127
|
+
=end
|
128
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quality_extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tyler Rick and others
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-01-11 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/quality_extensions/global_variable_set.rb
|
49
49
|
- lib/quality_extensions/hash/only.rb
|
50
50
|
- lib/quality_extensions/hash/to_date.rb
|
51
|
+
- lib/quality_extensions/hash/except.rb
|
51
52
|
- lib/quality_extensions/hash/all.rb
|
52
53
|
- lib/quality_extensions/hash/delete_unless.rb
|
53
54
|
- lib/quality_extensions/hash/to_query_string.rb
|
@@ -70,14 +71,15 @@ files:
|
|
70
71
|
- lib/quality_extensions/color/gradiate.rb
|
71
72
|
- lib/quality_extensions/color/rgb.rb
|
72
73
|
- lib/quality_extensions/enumerable/map_with_index.rb
|
74
|
+
- lib/quality_extensions/enumerable/every.rb
|
73
75
|
- lib/quality_extensions/enumerable/select_until.rb
|
74
76
|
- lib/quality_extensions/enumerable/select_while.rb
|
75
|
-
- lib/quality_extensions/enumerable/enum.rb
|
76
77
|
- lib/quality_extensions/regexp/rfc822.rb
|
77
78
|
- lib/quality_extensions/regexp/named_captures.rb
|
78
79
|
- lib/quality_extensions/regexp/join.rb
|
79
80
|
- lib/quality_extensions/all.rb
|
80
81
|
- lib/quality_extensions/safe_nil.rb
|
82
|
+
- lib/quality_extensions/numeric/diff.rb
|
81
83
|
- lib/quality_extensions/time/all.rb
|
82
84
|
- lib/quality_extensions/time/deprecated.rb
|
83
85
|
- lib/quality_extensions/test/assert_changed.rb
|
@@ -100,6 +102,7 @@ files:
|
|
100
102
|
- lib/quality_extensions/object/if_else.rb
|
101
103
|
- lib/quality_extensions/object/mcall.rb
|
102
104
|
- lib/quality_extensions/object/send_if.rb
|
105
|
+
- lib/quality_extensions/pathname.rb
|
103
106
|
- lib/quality_extensions/find/select.rb
|
104
107
|
- lib/quality_extensions/dictable.rb
|
105
108
|
- lib/quality_extensions/inspect_with.rb
|
@@ -133,6 +136,7 @@ files:
|
|
133
136
|
- lib/quality_extensions/module/remove_const.rb
|
134
137
|
- lib/quality_extensions/module/namespace.rb
|
135
138
|
- lib/quality_extensions/module/create_setter.rb
|
139
|
+
- lib/quality_extensions/fixnum/change_base.rb
|
136
140
|
- lib/quality_extensions/nil_method_missing.rb
|
137
141
|
- lib/quality_extensions/colored/toggleability.rb
|
138
142
|
- lib/quality_extensions/float/truncate.rb
|
@@ -1,69 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Author:: Tyler Rick
|
3
|
-
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
4
|
-
# License:: Ruby License
|
5
|
-
# Submit to Facets?:: Yes!
|
6
|
-
#++
|
7
|
-
|
8
|
-
require 'enumerator'
|
9
|
-
module Enumerable
|
10
|
-
|
11
|
-
# The core Enumerable module provides the following enumerator methods;
|
12
|
-
# * <tt>enum_cons()</tt>
|
13
|
-
# * <tt>enum_slice()</tt>
|
14
|
-
# * <tt>enum_with_index()</tt>
|
15
|
-
# but for some reason they didn't provide a generic <tt>enum()</tt> method for the cases they didn't think of!
|
16
|
-
#
|
17
|
-
# +enum+ lets you turn *any* iterator into a general-purpose <tt>Enumerator</tt>, which, according to the RDocs, is
|
18
|
-
# "A class which provides a method `<tt>each</tt>' to be used as an <tt>Enumerable</tt> object."
|
19
|
-
#
|
20
|
-
# This lets you turn any '<tt>each'-type</tt> iterator (<tt>each_byte</tt>, <tt>each_line</tt>, ...) into a
|
21
|
-
# '<tt>map</tt>'-type iterator (one that returns a collection), or into an array, etc.
|
22
|
-
#
|
23
|
-
# So if an object responds to <tt>:each_line</tt> but not to <tt>:map_lines</tt> or <tt>:lines</tt>, you could just do:
|
24
|
-
# object.enum(:each_line).map { block }
|
25
|
-
# object.enum(:each_line).min
|
26
|
-
# object.enum(:each_line).grep /pattern/
|
27
|
-
# lines = object.enum(:each_line).to_a
|
28
|
-
#
|
29
|
-
# If no iterator is specified, <tt>:each</tt> is assumed:
|
30
|
-
# object.enum.map { block }
|
31
|
-
#
|
32
|
-
# More examples:
|
33
|
-
# Dir.new('.').enum.to_a
|
34
|
-
# #=> ['file1', 'file2']
|
35
|
-
#
|
36
|
-
# "abc".enum(:each_byte).map{|byte| byte.chr.upcase}
|
37
|
-
# #=> ["A", "B", "C"]
|
38
|
-
#
|
39
|
-
def enum(iterator = :each)
|
40
|
-
Enumerable::Enumerator.new(self, iterator)
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
# _____ _
|
46
|
-
# |_ _|__ ___| |_
|
47
|
-
# | |/ _ \/ __| __|
|
48
|
-
# | | __/\__ \ |_
|
49
|
-
# |_|\___||___/\__|
|
50
|
-
#
|
51
|
-
=begin test
|
52
|
-
require 'test/unit'
|
53
|
-
|
54
|
-
class TheTest < Test::Unit::TestCase
|
55
|
-
def test_1
|
56
|
-
# @options.enum(:each).map { |key, value|
|
57
|
-
# values = [value].flatten
|
58
|
-
# key +
|
59
|
-
# (values.empty? ? " #{flatten.join(' ')}" : '')
|
60
|
-
# }.join(' ')
|
61
|
-
|
62
|
-
# Yes we could use the built-in Array#map method, but...not every class that provides iterators (each, ...) provides a map().
|
63
|
-
assert_equal ['A', 'B', 'C'], ['a', 'b', 'c'].enum(:each).map {|v| v.upcase}
|
64
|
-
end
|
65
|
-
def test_2
|
66
|
-
assert Dir.new('.').enum.to_a.size > 0
|
67
|
-
end
|
68
|
-
end
|
69
|
-
=end
|