wdd-ruby-ext 0.0.0 → 0.2.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/README.rdoc +11 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/wdd-ruby-ext/array.rb +6 -0
- data/lib/wdd-ruby-ext/hash.rb +7 -0
- data/lib/wdd-ruby-ext/http.rb +27 -0
- data/lib/wdd-ruby-ext/numbers.rb +38 -0
- data/lib/wdd-ruby-ext/object.rb +27 -0
- data/lib/wdd-ruby-ext/string.rb +83 -0
- data/lib/wdd-ruby-ext/system.rb +17 -0
- data/lib/wdd-ruby-ext/time.rb +55 -0
- data/lib/wdd-ruby-ext/utils/fixed_point.rb +89 -0
- data/lib/wdd-ruby-ext/utils/hash_object.rb +41 -0
- data/lib/wdd-ruby-ext/utils/helpers.rb +7 -0
- data/lib/wdd-ruby-ext/utils/simpledebug.rb +52 -0
- data/lib/wdd-ruby-ext/utils/time_gate.rb +42 -0
- data/lib/wdd-ruby-ext/utils.rb +6 -0
- data/lib/wdd-ruby-ext.rb +12 -0
- data/spec/lib/utils/fixed_point_spec.rb +139 -0
- data/spec/wdd-ruby-ext_spec.rb +0 -1
- data/wdd-ruby-ext.gemspec +71 -0
- metadata +45 -10
data/README.rdoc
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
= wdd-ruby-ext
|
2
2
|
|
3
|
-
|
3
|
+
Handy Ruby extensions.
|
4
|
+
|
5
|
+
I don't take credit for all of these. Some were
|
6
|
+
ripped from blog postings and other sources. I apologize for failing to give
|
7
|
+
credit where credit is due. I will try to give credit for new additions
|
8
|
+
added in the future and will happily give proper credit if I am alerted to
|
9
|
+
such.
|
4
10
|
|
5
11
|
== Note on Patches/Pull Requests
|
6
12
|
|
@@ -16,3 +22,7 @@ Description goes here.
|
|
16
22
|
== Copyright
|
17
23
|
|
18
24
|
Copyright (c) 2009 shock. See LICENSE for details.
|
25
|
+
<<<<<<< HEAD:README.rdoc
|
26
|
+
|
27
|
+
=======
|
28
|
+
>>>>>>> 0aa60a70e9983277e4d0ac757d74b7fde91aa1bf:README.rdoc
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ begin
|
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "wdd-ruby-ext"
|
8
|
-
gem.summary = %Q{Handy extensions to the Ruby base
|
8
|
+
gem.summary = %Q{Handy extensions to the Ruby base classes and other utilities.}
|
9
9
|
gem.description = %Q{Some of these are borrowed. Some are original. This gem simply provides a single place to source control them all for incorporation into other projects.}
|
10
10
|
gem.email = "billdoughty@capitalthought.com"
|
11
11
|
gem.homepage = "http://github.com/shock/wdd-ruby-ext"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
# Make the HTTP socket timeout 10 seconds
|
5
|
+
class BufferedIO #:nodoc: internal use only
|
6
|
+
def initialize(io)
|
7
|
+
@io = io
|
8
|
+
@read_timeout = 10 # overrides the default in the Ruby lib, which is 60 seconds.
|
9
|
+
@debug_output = nil
|
10
|
+
@rbuf = ''
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
module Net
|
16
|
+
class HTTP
|
17
|
+
|
18
|
+
# Convenience method to do HTTP GET with custom headers
|
19
|
+
def HTTP.get_with_headers(host, port, path, headers)
|
20
|
+
start(host, port) do |http|
|
21
|
+
return http.get(path, headers)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
module MinMaxComparison
|
3
|
+
# Returns the greater of the object's value or +value+
|
4
|
+
def max( value )
|
5
|
+
if value > self
|
6
|
+
value
|
7
|
+
else
|
8
|
+
self
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the lesser of the object's value or +value+
|
13
|
+
def min( value )
|
14
|
+
if value < self
|
15
|
+
value
|
16
|
+
else
|
17
|
+
self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Fixnum
|
23
|
+
include MinMaxComparison
|
24
|
+
end
|
25
|
+
|
26
|
+
class Rational
|
27
|
+
include MinMaxComparison
|
28
|
+
end
|
29
|
+
|
30
|
+
class Float
|
31
|
+
include MinMaxComparison
|
32
|
+
|
33
|
+
def precision(pre)
|
34
|
+
mult = 10 ** pre
|
35
|
+
(self * mult).truncate.to_f / mult
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
class Object
|
3
|
+
@@__duping_registry = {}
|
4
|
+
|
5
|
+
def deep_dup
|
6
|
+
return @@__duping_registry[object_id] if @@__duping_registry[object_id]
|
7
|
+
|
8
|
+
begin
|
9
|
+
deep_duping_obj = dup
|
10
|
+
rescue TypeError
|
11
|
+
return self
|
12
|
+
end
|
13
|
+
deep_duping_obj.instance_variables.each do |var|
|
14
|
+
val = deep_duping_obj.instance_variable_get(var)
|
15
|
+
begin
|
16
|
+
@@__duping_registry[object_id] = deep_duping_obj
|
17
|
+
val = val.deep_dup
|
18
|
+
rescue TypeError
|
19
|
+
next
|
20
|
+
ensure
|
21
|
+
@@__duping_registry[object_id] = nil
|
22
|
+
end
|
23
|
+
deep_duping_obj.instance_variable_set(var, val)
|
24
|
+
end
|
25
|
+
deep_duping_obj
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
|
2
|
+
class String
|
3
|
+
# Finds the longest commong substring betweent the two supplied strings
|
4
|
+
def self.lcs(s1, s2)
|
5
|
+
num=Array.new(s1.size){Array.new(s2.size)}
|
6
|
+
len,ans=0
|
7
|
+
|
8
|
+
longest_substr = ""
|
9
|
+
substr = ""
|
10
|
+
s1.scan(/./).each_with_index do |l1,i |
|
11
|
+
s2.scan(/./).each_with_index do |l2,j |
|
12
|
+
|
13
|
+
unless l1==l2
|
14
|
+
num[i][j]=[0,""]
|
15
|
+
else
|
16
|
+
if (i==0 || j==0)
|
17
|
+
num[i][j]=[1,l1]
|
18
|
+
else
|
19
|
+
num[i][j] = [1 + num[i-1][j-1][0], num[i-1][j-1][1] +l1]
|
20
|
+
end
|
21
|
+
if num[i][j][0] > len
|
22
|
+
len = ans = num[i][j][0]
|
23
|
+
longest_substr = num[i][j][1]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
longest_substr
|
29
|
+
end
|
30
|
+
|
31
|
+
# Performs multiple gsub operations in a single pass.
|
32
|
+
# +key_value_pairs+ is an array of [key,value] pairs where each key is a regular expression
|
33
|
+
# and the value is the value to substitute when that regexp is matched.
|
34
|
+
def mgsub(key_value_pairs=[].freeze)
|
35
|
+
regexp_fragments = key_value_pairs.collect { |k,v| k }
|
36
|
+
gsub(Regexp.union(*regexp_fragments)) do |match|
|
37
|
+
key_value_pairs.detect{|k,v| k =~ match}[1]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Performs multiple gsub operations in a single pass.
|
42
|
+
# +key_value_pairs+ is an array of [key,value] pairs where each key is a regular expression
|
43
|
+
# and the value is the value to substitute when that regexp is matched.
|
44
|
+
#
|
45
|
+
# Unlike mgsub, this method allows parenthesized subsections of the match string from the regexp
|
46
|
+
# to be embedded in the replace string. The normal variables are available in the replacement
|
47
|
+
# string.
|
48
|
+
#
|
49
|
+
# eg.
|
50
|
+
#
|
51
|
+
# >> "this is that".mgpsub( [ [/(that)/, 'really $1!'], [/this/, 'that'] ] )
|
52
|
+
# => that is really that!"
|
53
|
+
#
|
54
|
+
def mgpsub(key_value_pairs=[].freeze)
|
55
|
+
def mgpsub(string, key_value_pairs=[].freeze)
|
56
|
+
regexp_fragments = key_value_pairs.collect { |k,v| k }
|
57
|
+
string.gsub(Regexp.union(*regexp_fragments)) do |match|
|
58
|
+
replacement_term = key_value_pairs.detect{|k,v| k=~match}[1]
|
59
|
+
vars = %w{$1 $2 $3 $4 $5 $6 $7 $8 $9 $` $& $’}
|
60
|
+
vars.each do |var|
|
61
|
+
tm_safe_log var
|
62
|
+
tm_safe_log eval(var)||''
|
63
|
+
replacement_term.gsub!( Regexp.compile("\\"+var), eval(var)||'' )
|
64
|
+
end
|
65
|
+
replacement_term
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# trims the string to the nearest word boundary ensuring that the resulting length is less than max_length
|
71
|
+
def trim_to_word( max_length )
|
72
|
+
string = self
|
73
|
+
if string.length > max_length
|
74
|
+
string = string[0..max_length-4]
|
75
|
+
while string[-1,1] =~ /[\w]/ && string.length > 1
|
76
|
+
string = string[0..string.length-2]
|
77
|
+
end
|
78
|
+
string += "..."
|
79
|
+
end
|
80
|
+
string
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
module Process
|
3
|
+
# Returns the current process' resident memory size in KB. May not work on all OS's. Tested on Mac OS X only.
|
4
|
+
def self.mem_size
|
5
|
+
pid = Process.pid
|
6
|
+
mem = `ps -o rsz #{pid}`
|
7
|
+
mem.gsub!("RSZ", "").strip!
|
8
|
+
mem
|
9
|
+
end
|
10
|
+
|
11
|
+
# Prints the process' current resident memory size with an optional +position+ marker.
|
12
|
+
def self.show_mem position = "undefined"
|
13
|
+
mem = Process.mem_size
|
14
|
+
printf( "Resident Memory Size: #{mem}K - #{position}\n" )
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Date
|
2
|
+
|
3
|
+
def to_timezone
|
4
|
+
@day_start_timezone ||= ActiveSupport::TimeWithZone.new( nil, Time.zone, Time.utc( self.year, self.month, self.day ) )
|
5
|
+
end
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
class DateTime
|
10
|
+
LOG_TIME_FORMAT = "%a %Y-%m-%d %H:%M:%S"
|
11
|
+
DB_TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
|
12
|
+
|
13
|
+
# Format date and time for log timestamp
|
14
|
+
def ltf
|
15
|
+
strftime(LOG_TIME_FORMAT)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Format date and time for SQL
|
19
|
+
def dbf
|
20
|
+
strftime(DB_TIME_FORMAT)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Time
|
25
|
+
LOG_TIME_FORMAT = "%a %Y-%m-%d %H:%M:%S"
|
26
|
+
DB_TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
|
27
|
+
|
28
|
+
# Format date and time for log timestamp
|
29
|
+
def ltf
|
30
|
+
strftime(LOG_TIME_FORMAT)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Format date and time for SQL
|
34
|
+
def dbf
|
35
|
+
strftime(DB_TIME_FORMAT)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if defined? ActiveSupport::TimeWithZone
|
40
|
+
class ActiveSupport::TimeWithZone
|
41
|
+
LOG_TIME_FORMAT = "%a %Y-%m-%d %H:%M:%S"
|
42
|
+
DB_TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
|
43
|
+
|
44
|
+
# Format date and time for log timestamp
|
45
|
+
def ltf
|
46
|
+
strftime(LOG_TIME_FORMAT)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Format date and time for SQL
|
50
|
+
def dbf
|
51
|
+
strftime(DB_TIME_FORMAT)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
class FixedPoint
|
4
|
+
|
5
|
+
PRECISION = 2
|
6
|
+
|
7
|
+
ARITHMETIC_METHODS = %w{+ -}
|
8
|
+
COMPARE_METHODS = %w{> < >= <= <=>}
|
9
|
+
|
10
|
+
attr :value
|
11
|
+
attr :factor
|
12
|
+
attr :precision
|
13
|
+
|
14
|
+
def initialize( initial = 0.0, raw_value = nil, precision=PRECISION )
|
15
|
+
@precision = precision
|
16
|
+
@factor = 10**@precision
|
17
|
+
if raw_value
|
18
|
+
@value = raw_value
|
19
|
+
else
|
20
|
+
@value = (BigDecimal.new(initial.to_s.gsub(',',''), precision)*@factor).to_i
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
@value.to_s
|
26
|
+
"%.0#{@precision}f" % (@value.to_f/@factor)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_i
|
30
|
+
(@value / @factor).to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
def == obj
|
34
|
+
if obj.is_a? Numeric
|
35
|
+
@value == (obj * @factor).to_i
|
36
|
+
elsif obj.is_a? FixedPoint
|
37
|
+
@value == obj.value
|
38
|
+
else
|
39
|
+
false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def abs
|
44
|
+
if @value > 0
|
45
|
+
FixedPoint.new(0, @value, @precision)
|
46
|
+
else
|
47
|
+
FixedPoint.new(0, -@value, @precision)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def -@
|
52
|
+
FixedPoint.new(0, -@value, @precision)
|
53
|
+
end
|
54
|
+
|
55
|
+
def *( arg )
|
56
|
+
if arg.is_a? FixedPoint
|
57
|
+
result = (@value * arg.value)/arg.factor
|
58
|
+
else
|
59
|
+
result = (@value * (arg*@factor).to_i) / @factor
|
60
|
+
end
|
61
|
+
new_obj = FixedPoint.new(0, result.to_i, @precision)
|
62
|
+
end
|
63
|
+
|
64
|
+
def /( arg )
|
65
|
+
if arg.is_a? FixedPoint
|
66
|
+
result = (@value*arg.factor) * arg.value
|
67
|
+
else
|
68
|
+
result = (@value*@factor) / (arg*@factor).to_i
|
69
|
+
end
|
70
|
+
new_obj = FixedPoint.new(0, result.to_i, @precision)
|
71
|
+
end
|
72
|
+
|
73
|
+
def method_missing method, *args
|
74
|
+
if ARITHMETIC_METHODS.include? method.to_s
|
75
|
+
arg = (args[0] * @factor).to_i
|
76
|
+
result = @value.send(method, arg)
|
77
|
+
new_obj = FixedPoint.new(0, result.to_i, @precision)
|
78
|
+
elsif COMPARE_METHODS.include? method.to_s
|
79
|
+
arg = (args[0] * @factor).to_i
|
80
|
+
result = @value.send(method, arg)
|
81
|
+
else
|
82
|
+
super
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class HashObject
|
2
|
+
def initialize hash_obj, no_exception_on_missing_key = false
|
3
|
+
@hash_obj = hash_obj
|
4
|
+
@no_exception_on_missing_key = no_exception_on_missing_key
|
5
|
+
end
|
6
|
+
|
7
|
+
def [] key
|
8
|
+
@hash_obj[key]
|
9
|
+
end
|
10
|
+
|
11
|
+
def keys
|
12
|
+
return @hash_obj.keys
|
13
|
+
end
|
14
|
+
|
15
|
+
def merge hash
|
16
|
+
HashObject.new(@hash_obj.merge( hash ))
|
17
|
+
end
|
18
|
+
|
19
|
+
def merge! hash
|
20
|
+
@hash_obj.merge!( hash )
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing method, *args
|
25
|
+
key = method.to_s
|
26
|
+
if @hash_obj.keys.include? key
|
27
|
+
obj = @hash_obj[key]
|
28
|
+
obj = HashObject.new(obj) if obj.is_a? Hash
|
29
|
+
return obj
|
30
|
+
elsif @hash_obj.keys.include? key.to_sym
|
31
|
+
obj = @hash_obj[key.to_sym]
|
32
|
+
obj = HashObject.new(obj) if obj.is_a? Hash
|
33
|
+
return obj
|
34
|
+
elsif matches = key.match( /(\w*)=/ )
|
35
|
+
key = matches[1].to_sym
|
36
|
+
@hash_obj[key]=args.first
|
37
|
+
else
|
38
|
+
raise "No field in Hash object: #{key}" unless @no_exception_on_missing_key
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# require 'pp'
|
2
|
+
|
3
|
+
module WDD
|
4
|
+
module Utilities
|
5
|
+
module SimpleDebug
|
6
|
+
|
7
|
+
public
|
8
|
+
@__debugLevel = -1
|
9
|
+
@__prefix = ""
|
10
|
+
|
11
|
+
def setDebugLevel level
|
12
|
+
@__debugLevel = level
|
13
|
+
end
|
14
|
+
|
15
|
+
def setDebugPrefix __prefix
|
16
|
+
@__prefix = __prefix
|
17
|
+
end
|
18
|
+
|
19
|
+
def debugPrefix
|
20
|
+
@__prefix || ""
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_debug_level level
|
24
|
+
@__debugLevel = level
|
25
|
+
end
|
26
|
+
|
27
|
+
def __debugLevel
|
28
|
+
return @__debugLevel
|
29
|
+
end
|
30
|
+
|
31
|
+
def debugLevel
|
32
|
+
@__debugLevel
|
33
|
+
end
|
34
|
+
|
35
|
+
def debug_msg message, level=0
|
36
|
+
@__debugLevel ||= -1
|
37
|
+
if( level <= @__debugLevel )
|
38
|
+
puts debugPrefix + message
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def show_msg message
|
43
|
+
puts debugPrefix + message
|
44
|
+
end
|
45
|
+
|
46
|
+
def error_msg message, level=0
|
47
|
+
puts debugPrefix + "ERROR: " + message
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# TimeGate is a time-based latch.
|
2
|
+
# When intialized and set with a time period, +wait+ can be called to block the current thread's execution
|
3
|
+
# until the time period has elapsed.
|
4
|
+
#
|
5
|
+
# The idea is that once set, the thread can go about doing other work, then at some point
|
6
|
+
# wait on the gate to ensure that a certain amount of time has passed before continuing.
|
7
|
+
# This is specifically useful for throttling API calls.
|
8
|
+
module WDD
|
9
|
+
module Utilities
|
10
|
+
class TimeGate
|
11
|
+
def set seconds
|
12
|
+
@gate_time = Time.now + seconds
|
13
|
+
end
|
14
|
+
|
15
|
+
# Waits until the gate is opened.
|
16
|
+
# +block+ - true by default. If false, the method will not block, but will return the amount of time
|
17
|
+
# left before the gate opens.
|
18
|
+
# An optional Ruby block can be passed when +block+ is true that will be evaluated
|
19
|
+
# every 0.2 seconds. If the block evaluates to false, the latch is released and this method returns.
|
20
|
+
def wait block = true
|
21
|
+
if block
|
22
|
+
guard = block_given? ? yield : true
|
23
|
+
while Time.now < @gate_time && guard do
|
24
|
+
sleep 0.2
|
25
|
+
end
|
26
|
+
else
|
27
|
+
Time.now < @gate_time
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@gate_time = Time.now
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.elapsed_time &block
|
37
|
+
start_time = Time.now
|
38
|
+
yield
|
39
|
+
Time.now - start_time
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/wdd-ruby-ext.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Collection of general and useful Ruby class extensions
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'wdd-ruby-ext/system'
|
5
|
+
require 'wdd-ruby-ext/object'
|
6
|
+
require 'wdd-ruby-ext/array'
|
7
|
+
require 'wdd-ruby-ext/hash'
|
8
|
+
require 'wdd-ruby-ext/string'
|
9
|
+
require 'wdd-ruby-ext/http'
|
10
|
+
require 'wdd-ruby-ext/time'
|
11
|
+
require 'wdd-ruby-ext/numbers'
|
12
|
+
require 'wdd-ruby-ext/utils'
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec/autorun'
|
2
|
+
require 'spec/runner/formatter/text_mate_formatter'
|
3
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
4
|
+
|
5
|
+
describe FixedPoint do
|
6
|
+
it "defaults to zero on creation" do
|
7
|
+
c = FixedPoint.new
|
8
|
+
c.should == 0
|
9
|
+
end
|
10
|
+
|
11
|
+
it "initializes from a floating point number" do
|
12
|
+
c = FixedPoint.new(3.33)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "initializes from a string" do
|
16
|
+
c = FixedPoint.new('3.33')
|
17
|
+
c.value.should == 333
|
18
|
+
end
|
19
|
+
|
20
|
+
it "converts to string with two decimal place" do
|
21
|
+
c = FixedPoint.new(3.33)
|
22
|
+
c.to_s.should == "3.33"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "has equality with Fixnum" do
|
26
|
+
c = FixedPoint.new(10)
|
27
|
+
c.should == 10
|
28
|
+
c.should_not == 9
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has equality with Float" do
|
32
|
+
c = FixedPoint.new(1.11)
|
33
|
+
c.should == 1.11
|
34
|
+
c.should_not == 9.0
|
35
|
+
end
|
36
|
+
|
37
|
+
it "has equality with FixedPoint" do
|
38
|
+
c = FixedPoint.new(10)
|
39
|
+
c.should == FixedPoint.new(10.0)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "adds like a Float" do
|
43
|
+
c = FixedPoint.new(3.33)
|
44
|
+
d = c + 10.3
|
45
|
+
d.is_a?(FixedPoint).should == true
|
46
|
+
d.should == 13.63
|
47
|
+
d += 0.33
|
48
|
+
d.should == 13.96
|
49
|
+
end
|
50
|
+
|
51
|
+
it "subtracts like a Float" do
|
52
|
+
c = FixedPoint.new(3.33)
|
53
|
+
d = c - 3
|
54
|
+
d.is_a?(FixedPoint).should == true
|
55
|
+
d.should == 0.33
|
56
|
+
d -= 0.33
|
57
|
+
d.should == 0
|
58
|
+
end
|
59
|
+
|
60
|
+
it "multiplies like a Float" do
|
61
|
+
c = FixedPoint.new(3.33)
|
62
|
+
d = c * 3
|
63
|
+
d.is_a?(FixedPoint).should == true
|
64
|
+
d.should == 9.99
|
65
|
+
end
|
66
|
+
|
67
|
+
it "divides like a Float" do
|
68
|
+
c = FixedPoint.new(3.33)
|
69
|
+
d = c / 3
|
70
|
+
d.is_a?(FixedPoint).should == true
|
71
|
+
d.should == 1.11
|
72
|
+
end
|
73
|
+
|
74
|
+
it "adds with itself" do
|
75
|
+
a = FixedPoint.new(11.12)
|
76
|
+
b = FixedPoint.new(2.12)
|
77
|
+
(a+b).should == 13.24
|
78
|
+
end
|
79
|
+
|
80
|
+
it "multiplies with itself" do
|
81
|
+
a = FixedPoint.new(11.12)
|
82
|
+
b = FixedPoint.new(2.00)
|
83
|
+
(a*b).should == 22.24
|
84
|
+
end
|
85
|
+
|
86
|
+
it "multiplies with itself at different precisions" do
|
87
|
+
a = FixedPoint.new(1000.00)
|
88
|
+
b = FixedPoint.new(0.005, nil, 4)
|
89
|
+
c = (a*b)
|
90
|
+
c.should == 5
|
91
|
+
end
|
92
|
+
|
93
|
+
it "keeps the left operator's precision when multiplying with itself" do
|
94
|
+
a = FixedPoint.new(1000.00)
|
95
|
+
b = FixedPoint.new(0.005, nil, 4)
|
96
|
+
c = (b*a)
|
97
|
+
c.precision.should == 4
|
98
|
+
end
|
99
|
+
|
100
|
+
it "compares to a Float" do
|
101
|
+
c = FixedPoint.new(3.33)
|
102
|
+
(c > 3.0).should == true
|
103
|
+
(c < 4.0).should == true
|
104
|
+
(c <=> 4.0).should == -1
|
105
|
+
(c <=> 3.0).should == 1
|
106
|
+
(c <=> 3.33).should == 0
|
107
|
+
end
|
108
|
+
|
109
|
+
it "compares to a Fixnum" do
|
110
|
+
c = FixedPoint.new(3.33)
|
111
|
+
(c > 3).should == true
|
112
|
+
(c < 4).should == true
|
113
|
+
(c <=> 4).should == -1
|
114
|
+
(c <=> 3).should == 1
|
115
|
+
end
|
116
|
+
|
117
|
+
it "compares to a FixedPoint" do
|
118
|
+
c = FixedPoint.new(3.33)
|
119
|
+
(c > FixedPoint.new(3)).should == true
|
120
|
+
(c < FixedPoint.new(4)).should == true
|
121
|
+
(c <=> FixedPoint.new(4)).should == -1
|
122
|
+
(c <=> FixedPoint.new(3)).should == 1
|
123
|
+
end
|
124
|
+
|
125
|
+
it "handles negatives" do
|
126
|
+
c = FixedPoint.new(-13.33)
|
127
|
+
c.should be < 0
|
128
|
+
(c*c).should be > 0
|
129
|
+
end
|
130
|
+
|
131
|
+
it "abs works" do
|
132
|
+
c = FixedPoint.new(13.33)
|
133
|
+
c.abs.should == 13.33
|
134
|
+
c = FixedPoint.new(-13.33)
|
135
|
+
c.abs.should == 13.33
|
136
|
+
c.abs.should_not === c
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
data/spec/wdd-ruby-ext_spec.rb
CHANGED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{wdd-ruby-ext}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["shock"]
|
12
|
+
s.date = %q{2010-12-29}
|
13
|
+
s.description = %q{Some of these are borrowed. Some are original. This gem simply provides a single place to source control them all for incorporation into other projects.}
|
14
|
+
s.email = %q{billdoughty@capitalthought.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/wdd-ruby-ext.rb",
|
27
|
+
"lib/wdd-ruby-ext/array.rb",
|
28
|
+
"lib/wdd-ruby-ext/hash.rb",
|
29
|
+
"lib/wdd-ruby-ext/http.rb",
|
30
|
+
"lib/wdd-ruby-ext/numbers.rb",
|
31
|
+
"lib/wdd-ruby-ext/object.rb",
|
32
|
+
"lib/wdd-ruby-ext/string.rb",
|
33
|
+
"lib/wdd-ruby-ext/system.rb",
|
34
|
+
"lib/wdd-ruby-ext/time.rb",
|
35
|
+
"lib/wdd-ruby-ext/utils.rb",
|
36
|
+
"lib/wdd-ruby-ext/utils/fixed_point.rb",
|
37
|
+
"lib/wdd-ruby-ext/utils/hash_object.rb",
|
38
|
+
"lib/wdd-ruby-ext/utils/helpers.rb",
|
39
|
+
"lib/wdd-ruby-ext/utils/simpledebug.rb",
|
40
|
+
"lib/wdd-ruby-ext/utils/time_gate.rb",
|
41
|
+
"spec/lib/utils/fixed_point_spec.rb",
|
42
|
+
"spec/spec.opts",
|
43
|
+
"spec/spec_helper.rb",
|
44
|
+
"spec/wdd-ruby-ext_spec.rb",
|
45
|
+
"wdd-ruby-ext.gemspec"
|
46
|
+
]
|
47
|
+
s.homepage = %q{http://github.com/shock/wdd-ruby-ext}
|
48
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
49
|
+
s.require_paths = ["lib"]
|
50
|
+
s.rubygems_version = %q{1.3.7}
|
51
|
+
s.summary = %q{Handy extensions to the Ruby base classes and other utilities.}
|
52
|
+
s.test_files = [
|
53
|
+
"spec/lib/utils/fixed_point_spec.rb",
|
54
|
+
"spec/spec_helper.rb",
|
55
|
+
"spec/wdd-ruby-ext_spec.rb"
|
56
|
+
]
|
57
|
+
|
58
|
+
if s.respond_to? :specification_version then
|
59
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
60
|
+
s.specification_version = 3
|
61
|
+
|
62
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
63
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
66
|
+
end
|
67
|
+
else
|
68
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wdd-ruby-ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- shock
|
@@ -9,19 +15,25 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-12-29 00:00:00 -06:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: rspec
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 2
|
33
|
+
- 9
|
23
34
|
version: 1.2.9
|
24
|
-
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
25
37
|
description: Some of these are borrowed. Some are original. This gem simply provides a single place to source control them all for incorporation into other projects.
|
26
38
|
email: billdoughty@capitalthought.com
|
27
39
|
executables: []
|
@@ -39,9 +51,25 @@ files:
|
|
39
51
|
- Rakefile
|
40
52
|
- VERSION
|
41
53
|
- lib/wdd-ruby-ext.rb
|
54
|
+
- lib/wdd-ruby-ext/array.rb
|
55
|
+
- lib/wdd-ruby-ext/hash.rb
|
56
|
+
- lib/wdd-ruby-ext/http.rb
|
57
|
+
- lib/wdd-ruby-ext/numbers.rb
|
58
|
+
- lib/wdd-ruby-ext/object.rb
|
59
|
+
- lib/wdd-ruby-ext/string.rb
|
60
|
+
- lib/wdd-ruby-ext/system.rb
|
61
|
+
- lib/wdd-ruby-ext/time.rb
|
62
|
+
- lib/wdd-ruby-ext/utils.rb
|
63
|
+
- lib/wdd-ruby-ext/utils/fixed_point.rb
|
64
|
+
- lib/wdd-ruby-ext/utils/hash_object.rb
|
65
|
+
- lib/wdd-ruby-ext/utils/helpers.rb
|
66
|
+
- lib/wdd-ruby-ext/utils/simpledebug.rb
|
67
|
+
- lib/wdd-ruby-ext/utils/time_gate.rb
|
68
|
+
- spec/lib/utils/fixed_point_spec.rb
|
42
69
|
- spec/spec.opts
|
43
70
|
- spec/spec_helper.rb
|
44
71
|
- spec/wdd-ruby-ext_spec.rb
|
72
|
+
- wdd-ruby-ext.gemspec
|
45
73
|
has_rdoc: true
|
46
74
|
homepage: http://github.com/shock/wdd-ruby-ext
|
47
75
|
licenses: []
|
@@ -52,24 +80,31 @@ rdoc_options:
|
|
52
80
|
require_paths:
|
53
81
|
- lib
|
54
82
|
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
55
84
|
requirements:
|
56
85
|
- - ">="
|
57
86
|
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
58
90
|
version: "0"
|
59
|
-
version:
|
60
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
61
93
|
requirements:
|
62
94
|
- - ">="
|
63
95
|
- !ruby/object:Gem::Version
|
96
|
+
hash: 3
|
97
|
+
segments:
|
98
|
+
- 0
|
64
99
|
version: "0"
|
65
|
-
version:
|
66
100
|
requirements: []
|
67
101
|
|
68
102
|
rubyforge_project:
|
69
|
-
rubygems_version: 1.3.
|
103
|
+
rubygems_version: 1.3.7
|
70
104
|
signing_key:
|
71
105
|
specification_version: 3
|
72
|
-
summary: Handy extensions to the Ruby base
|
106
|
+
summary: Handy extensions to the Ruby base classes and other utilities.
|
73
107
|
test_files:
|
108
|
+
- spec/lib/utils/fixed_point_spec.rb
|
74
109
|
- spec/spec_helper.rb
|
75
110
|
- spec/wdd-ruby-ext_spec.rb
|