Class: TimeMath::Op

Inherits:
Object
  • Object
show all
Defined in:
lib/time_math/op.rb

Overview

Op is value object, incapsulating several operations performed on time unit. The names of operations are the same the single unit can perform, first parameter is always a unit.

Ops can be created by TimeMath::Op.new or with pretty shortcut TimeMath().

Available usages:

# 1. chain operations:
# without Op: 10:25 at first day of next week:
TimeMath.min.advance(TimeMath.hour.advance(TimeMath.week.ceil(tm), 10), 25)
# FOOOOOO
# ...but with Op:
TimeMath(tm).ceil(:week).advance(:hour, 10).advance(:min, 25).call

# 2. chain operations on multiple objects:
TimeMath(tm1, tm2, tm3).ceil(:week).advance(:hour, 10).advance(:min, 25).call
# or
TimeMath([array_of_times]).ceil(:week).advance(:hour, 10).advance(:min, 25).call

# 3. preparing operation to be used on any objects:
op = TimeMath().ceil(:week).advance(:hour, 10).advance(:min, 25)
op.call(tm)
op.call(tm1, tm2, tm3)
op.call(array_of_times)
# or even block-ish behavior:
[tm1, tm2, tm3].map(&op)

Note that Op also plays well with Sequence (see its docs for more).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*arguments) ⇒ Op

Creates Op. Could (and recommended be also by its alias -- just TimeMath(*arguments).

Parameters:

  • arguments

    one, or several, or an array of time-y values (Time, Date, DateTime).


45
46
47
48
# File 'lib/time_math/op.rb', line 45

def initialize(*arguments)
  @arguments = arguments
  @operations = []
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments


38
39
40
# File 'lib/time_math/op.rb', line 38

def arguments
  @arguments
end

#operationsObject (readonly)

Returns the value of attribute operations


38
39
40
# File 'lib/time_math/op.rb', line 38

def operations
  @operations
end

Instance Method Details

#==(other) ⇒ Object


165
166
167
168
# File 'lib/time_math/op.rb', line 165

def ==(other)
  self.class == other.class && operations == other.operations &&
    arguments == other.arguments
end

#advance(unit, amount = 1) ⇒ Op

Non-destructive version of #advance!.

Parameters:

  • unit (Symbol)
  • amount (Numeric) (defaults to: 1)

    how many units to advance.

Returns:


142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#advance!(unit, amount = 1) ⇒ self

Adds Units::Base#advance to list of operations.

Parameters:

  • unit (Symbol)
  • amount (Numeric) (defaults to: 1)

    how many units to advance.

Returns:

  • (self)

142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#call(*tms) ⇒ Time, ...

Performs op. If an Op was created with arguments, just performs all operations on them and returns the result. If it was created without arguments, performs all operations on arguments provided to call.

Parameters:

  • tms

    one, or several, or an array of time-y values; should not be passed if Op was created with arguments.

Returns:

  • (Time, Date, DateTime, Array)

    one, or an array of processed arguments


177
178
179
180
181
182
183
184
# File 'lib/time_math/op.rb', line 177

def call(*tms)
  unless @arguments.empty?
    tms.empty? or raise(ArgumentError, 'Op arguments is already set, use call()')
    tms = @arguments
  end
  res = [*tms].flatten.map(&method(:perform))
  tms.count == 1 && Util.timey?(tms.first) ? res.first : res
end

#ceil(unit, span = 1) ⇒ Op

Non-destructive version of #ceil!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to ceil to.

Returns:


142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#ceil!(unit, span = 1) ⇒ self

Adds Units::Base#ceil to list of operations.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to ceil to.

Returns:

  • (self)

142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#decrease(unit, amount = 1) ⇒ Op

Non-destructive version of #decrease!.

Parameters:

  • unit (Symbol)
  • amount (Numeric) (defaults to: 1)

    how many units to decrease.

Returns:


142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#decrease!(unit, amount = 1) ⇒ self

Adds Units::Base#decrease to list of operations.

Parameters:

  • unit (Symbol)
  • amount (Numeric) (defaults to: 1)

    how many units to decrease.

Returns:

  • (self)

142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#floor(unit, span = 1) ⇒ Op

Non-destructive version of #floor!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to floor to.

Returns:


142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#floor!(unit, span = 1) ⇒ self

Adds Units::Base#floor to list of operations.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to floor to.

Returns:

  • (self)

142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#inspectObject


154
155
156
# File 'lib/time_math/op.rb', line 154

def inspect
  "#<#{self.class}#{inspect_args}" + inspect_operations + '>'
end

#next(unit, span = 1) ⇒ Op

Non-destructive version of #next!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to ceil to.

Returns:


142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#next!(unit, span = 1) ⇒ self

Adds Units::Base#next to list of operations.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to ceil to.

Returns:

  • (self)

142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#prev(unit, span = 1) ⇒ Op

Non-destructive version of #prev!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to floor to.

Returns:


142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#prev!(unit, span = 1) ⇒ self

Adds Units::Base#prev to list of operations.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to floor to.

Returns:

  • (self)

142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#round(unit, span = 1) ⇒ Op

Non-destructive version of #round!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to round to.

Returns:


142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#round!(unit, span = 1) ⇒ self

Adds Units::Base#round to list of operations.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to round to.

Returns:

  • (self)

142
143
144
145
146
147
148
149
150
151
152
# File 'lib/time_math/op.rb', line 142

OPERATIONS.each do |op|
  define_method "#{op}!" do |unit, *args|
    Units.names.include?(unit) or raise(ArgumentError, "Unknown unit #{unit}")
    @operations << [op, unit, args]
    self
  end

  define_method op do |unit, *args|
    dup.send("#{op}!", unit, *args)
  end
end

#to_procProc

Allows to use Op as a block:

timestamps.map(&TimeMath().ceil(:week).advance(:day, 1))

Returns:

  • (Proc)

192
193
194
# File 'lib/time_math/op.rb', line 192

def to_proc
  method(:call).to_proc
end