Class: Reading::Item::TimeLength
- Includes:
- Comparable
- Defined in:
- lib/reading/item/time_length.rb
Overview
The length of an item when it is a time, as opposed to pages. (Pages are represented simply with an Integer or Float.)
Instance Attribute Summary collapse
-
#value ⇒ Object
readonly
in total minutes.
Class Method Summary collapse
-
.from_pages(pages) ⇒ TimeLength
Builds a TimeLength based on a page count.
-
.pages_to_minutes(pages) ⇒ Integer
Converts a page count to minutes.
-
.parse(string) ⇒ TimeLength?
Builds a TimeLength from a string.
Instance Method Summary collapse
- #*(other) ⇒ TimeLength
- #+(other) ⇒ TimeLength
- #-(other) ⇒ TimeLength
- #/(other) ⇒ TimeLength
- #<=>(other) ⇒ Integer
- #coerce(other) ⇒ Object
-
#eql?(other) ⇒ Boolean
Must be implemented for hash key equality checks.
-
#hash ⇒ Integer
Must be implemented along with #eql? for hash key equality checks.
-
#hours ⇒ Numeric
Only the hours, e.g.
-
#initialize(value) ⇒ TimeLength
constructor
A new instance of TimeLength.
-
#minutes ⇒ Numeric
Only the hours, e.g.
-
#percentage_of(other) ⇒ TimeLength
For relativizing progress to a percentage of amount.
-
#round ⇒ TimeLength
A copy of self with a rounded @value.
-
#to_i ⇒ Integer
To pages.
-
#to_i_if_whole ⇒ TimeLength
A non-mutating version of #to_i_if_whole! for compatibility with the refinement Numeric#to_i_if_whole.
-
#to_i_if_whole! ⇒ TimeLength
Converts @value to an Integer if it’s a whole number, and returns self.
-
#to_s ⇒ String
A string in “h:mm” format.
- #zero? ⇒ Boolean
Constructor Details
#initialize(value) ⇒ TimeLength
Returns a new instance of TimeLength.
11 12 13 |
# File 'lib/reading/item/time_length.rb', line 11 def initialize(value) @value = value end |
Instance Attribute Details
#value ⇒ Object (readonly)
in total minutes
8 9 10 |
# File 'lib/reading/item/time_length.rb', line 8 def value @value end |
Class Method Details
.from_pages(pages) ⇒ TimeLength
Builds a TimeLength based on a page count.
28 29 30 |
# File 'lib/reading/item/time_length.rb', line 28 def self.from_pages(pages) new(pages_to_minutes(pages)) end |
.pages_to_minutes(pages) ⇒ Integer
Converts a page count to minutes.
35 36 37 |
# File 'lib/reading/item/time_length.rb', line 35 def self.pages_to_minutes(pages) (pages.to_f / Config.hash.fetch(:pages_per_hour) * 60) end |
.parse(string) ⇒ TimeLength?
Builds a TimeLength from a string.
18 19 20 21 22 23 |
# File 'lib/reading/item/time_length.rb', line 18 def self.parse(string) return nil unless string.match?(/\A\d+:\d\d\z/) hours, minutes = string.split(":").map(&:to_i) new((hours * 60) + minutes) end |
Instance Method Details
#*(other) ⇒ TimeLength
125 126 127 128 129 130 131 |
# File 'lib/reading/item/time_length.rb', line 125 def *(other) if other.is_a? Numeric self.class.new(value * other).to_i_if_whole! else raise TypeError, "TimeLength can't be multiplied by #{other.class}." end end |
#+(other) ⇒ TimeLength
101 102 103 104 105 106 107 108 109 |
# File 'lib/reading/item/time_length.rb', line 101 def +(other) if other.is_a? TimeLength self.class.new(value + other.value) elsif other.is_a? Numeric self.class.new(value + self.class.pages_to_minutes(other)) else raise TypeError, "#{other.class} can't be added to TimeLength." end end |
#-(other) ⇒ TimeLength
113 114 115 116 117 118 119 120 121 |
# File 'lib/reading/item/time_length.rb', line 113 def -(other) if other.is_a? TimeLength self.class.new(value - other.value) elsif other.is_a? Numeric self.class.new(value - self.class.pages_to_minutes(other)) else raise TypeError, "#{other.class} can't be subtracted from TimeLength." end end |
#/(other) ⇒ TimeLength
135 136 137 138 139 140 141 |
# File 'lib/reading/item/time_length.rb', line 135 def /(other) if other.is_a? Numeric self.class.new(value / other).to_i_if_whole! else raise TypeError, "TimeLength can't be divided by #{other.class}." end end |
#<=>(other) ⇒ Integer
166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/reading/item/time_length.rb', line 166 def <=>(other) return 1 if other.nil? if other.is_a? Numeric other = self.class.from_pages(other) end unless other.is_a? TimeLength raise TypeError, "TimeLength can't be compared to #{other.class} #{other}." end value <=> other.value end |
#coerce(other) ⇒ Object
156 157 158 159 160 161 162 |
# File 'lib/reading/item/time_length.rb', line 156 def coerce(other) if other.is_a? Numeric [self.class.from_pages(other), self] else raise TypeError, "#{other.class} can't be coerced into a TimeLength." end end |
#eql?(other) ⇒ Boolean
Must be implemented for hash key equality checks.
183 184 185 |
# File 'lib/reading/item/time_length.rb', line 183 def eql?(other) hash == other.hash end |
#hash ⇒ Integer
Must be implemented along with #eql? for hash key equality checks.
189 190 191 |
# File 'lib/reading/item/time_length.rb', line 189 def hash value end |
#hours ⇒ Numeric
Only the hours, e.g. the “h” value in “h:mm”.
41 42 43 |
# File 'lib/reading/item/time_length.rb', line 41 def hours value.to_i / 60 end |
#minutes ⇒ Numeric
Only the hours, e.g. the “mm” value in “h:mm”.
47 48 49 |
# File 'lib/reading/item/time_length.rb', line 47 def minutes value % 60 end |
#percentage_of(other) ⇒ TimeLength
For relativizing progress to a percentage of amount.
146 147 148 149 150 151 152 |
# File 'lib/reading/item/time_length.rb', line 146 def percentage_of(other) if other.is_a? TimeLength value.to_f / other.value else raise TypeError, "TimeLength can't be percent-divided by #{other.class}." end end |
#round ⇒ TimeLength
A copy of self with a rounded @value.
70 71 72 |
# File 'lib/reading/item/time_length.rb', line 70 def round self.class.new(@value.round) end |
#to_i ⇒ Integer
To pages.
59 60 61 |
# File 'lib/reading/item/time_length.rb', line 59 def to_i ((value / 60.0) * Config.hash.fetch(:pages_per_hour)).to_i end |
#to_i_if_whole ⇒ TimeLength
A non-mutating version of #to_i_if_whole! for compatibility with the refinement Numeric#to_i_if_whole.
89 90 91 92 93 94 95 96 97 |
# File 'lib/reading/item/time_length.rb', line 89 def to_i_if_whole if @value.is_a?(Float) && @value.nan? return self.class.new(0) else return self if @value.is_a?(Integer) || @value.to_i != @value self.class.new(@value.to_i) end end |
#to_i_if_whole! ⇒ TimeLength
Converts @value to an Integer if it’s a whole number, and returns self.
76 77 78 79 80 81 82 83 84 |
# File 'lib/reading/item/time_length.rb', line 76 def to_i_if_whole! if @value.is_a?(Float) && @value.nan? @value = 0 elsif @value.to_i == @value @value = @value.to_i end self end |
#to_s ⇒ String
A string in “h:mm” format.
53 54 55 |
# File 'lib/reading/item/time_length.rb', line 53 def to_s "#{hours}:#{minutes.round.to_s.rjust(2, "0")} or #{(value / 60.0 * Config.hash.fetch(:pages_per_hour)).round} pages" end |
#zero? ⇒ Boolean
64 65 66 |
# File 'lib/reading/item/time_length.rb', line 64 def zero? value.zero? end |