Sunday, December 13, 2015

Implementing Abs using Objects



def absolute(x)
  if x > 0
    x
  elsif x == 0
    0
  elsif x < 0
    -x
  end
end

# p absolute(0)


class GreaterThan
  attr_reader :number

  def initialize(value, number)
    @value, @number = value, number
  end

  def evaluate
    result[@number.send(:>, @value).class]
  end

  private

  def result
    {TrueClass => @number}
  end
end

# c = GreaterThan.new(0, -2)
#
# p c.evaluate

class LessThan
  attr_reader :number

  def initialize(value, number)
    @value, @number = value, number
  end

  def evaluate
    result[@number.send(:<, @value).class]
  end

  private

  def result
    {TrueClass => -@number}
  end
end


# c = LessThan.new(0, -2)
#
# p c.evaluate


class EqualTo
  attr_reader :number

  def initialize(value, number)
    @value, @number = value, number
  end

  def evaluate
    result[@number.send(:==, @value).class]
  end

  private

  def result
    {TrueClass => 0}
  end
end


# c = EqualTo.new(0, 0)
#
# p c.evaluate


def obzolute(x)
   [GreaterThan.new(0, x), LessThan.new(0, x), EqualTo.new(0,x)].each do |predicate|
      unless predicate.evaluate.nil?
        return predicate.evaluate
      end
   end
end

p obzolute(0)
p obzolute(-1)
p obzolute(2)


Second Version

class Predicate
  def initialize(operator, value)
    @operator, @value = operator, value
  end
 
  def evaluate
    @value.send(@operator.to_sym, 0)
  end
 
  def result
    {'>' => @value, '==' => 0, '<' => -@value}
  end
 
end

p1 = Predicate.new('<', -1)

p (p1.evaluate and p1.result['<'])


p2 = Predicate.new('==', 0)

p (p2.evaluate and p2.result['=='])


p3 = Predicate.new('>', 2)

p (p3.evaluate and p3.result['>'])