Case Ruby statement with multiple variables using an array

I would like to compare several variables for case-case, and currently I believe that overriding the equals (===) operator for Array is the best way to do this. Is this the best way?

Here is a usage example:

def deposit_apr deposit,apr 
  # deposit: can be nil or 2 length Array of [nil or Float, String]  
  # apr: can be nil or Float     
  case [deposit,apr] 
    when [[Float,String],Float] 
      puts "#{deposit[0]} #{deposit[1]}, #{apr*100.0}% APR"
    when [[nil,String],Float] 
      puts "#{apr*100.0}% APR on deposits greater than 100 #{deposit[1]}"
    when [[Float,String],nil] 
      puts "#{deposit[0]} #{deposit[1]}"
    else 
      puts 'N/A' 
  end
end

The only problem is that the Array case operator is equal to the operator does not apply the case equal to the elements of the array.

ruby-1.9.2-p0 > deposit_apr([656.00,'rupees'],0.065)
N/A

This will happen if I override, but I'm not sure what I would violate if I did:

class Array
  def ===(other)
    result = true
    self.zip(other) {|bp,ap| result &&= bp === ap}
    result
  end
end

Now everything works:

ruby-1.9.2-p0 > deposit_apr([656.00,'rupees'],0.065)
656.0 rupees, 6.5% APR

Am I missing something?

+3
source share
3 answers

, case , , , , , . ( , , .)

"no monkey patching" . , , . , , .

, . , Duck Typing, . , , float? "N/A", , .

, , , . ( , , ).

, , , , -type class (Deposit), .

, , AP nil 0.0% APR.

class Deposit
  def initialize(amount, unit='USD', options={})
    @amount = amount.to_f # `nil` => 0.0
    @unit   = unit.to_s   # Example assumes unit is always present
    @apr    = options.fetch(:apr, 0.0).to_f # `apr: nil` => 0.0
  end
end

"", case.

class Deposit

  # ... lines omitted

  def to_s
    string = "#{@amount} #{@unit}"
    string << ", #{@apr * 100.0}% APR" if @apr > 0.0
    string
  end
end

d = Deposit.new(656.00, 'rupees', apr: 0.065)
d.to_s
# => "656.0 rupees, 6.5% APR"

e = Deposit.new(100, 'USD', apr: nil)
e.to_s
# => "100.0 USD"

f = Deposit.new(100, 'USD')
f.to_s
# => "100.0 USD"

. case case, , . case , .

+8

-, Array , , , Array.

+2

. - , - .

( ), .

, - , - ?

IMO uses catch exception and fix source of problem, don't try to fix problem somewhere in between

-1
source

Source: https://habr.com/ru/post/1788712/


All Articles