2016-11-19 2 views
4

Lassen Sie uns sagen, ich eine Calculator-Klasse erstellen, die durch die Manipulation von Elementen in einem Array funktioniert - innerhalb dieser Klasse definiere ich mehrere Methoden: addieren, subtrahieren, multiplizieren, dividieren. Ich mag jede Methode die gleichen Fehler zu erhöhen, wenn es existiert nur 1 oder weniger Elemente in der Anordnung, so etwas wie:Ruby - Wie man denselben Fehler für mehrere Methoden erhöht, ohne es mehrmals zu schreiben?

class Calculator 
# ... 
def add 
    if @array.length < 2 
    raise 'Not Enough Elements' 
    else 
    @array << @array.pop + @array.pop 
    end 
end 
# ... 
end 

ich einen Zustand schreiben konnte den Fehler in jedes Verfahren zu erhöhen, aber das scheint sehr mühsam und un-Rubin. Würde es einen Weg geben, den erhöhten Fehler auf alle Methoden anzuwenden, die es benötigen würden, um das ganze Tippen zu speichern?

+1

Was passiert bei einer unären oder n-fachen Operation? : < – user2864740

Antwort

3

Eine der Optionen, die Länge Bewegungslogik Überprüfung würde in seinem eigenen Verfahren und unter Verwendung, wo nötig:

class Calculator 
    def add 
    check_array_length 
    # rest of the method 
    end 

    private 

    def check_array_length 
    raise 'Not Enough Elements' if @array.length < 2 
    end 
end 

Wenn Sie @array im initialize Verfahren einstellen, die Sie auf der Frühphase erhöhen könnte, sagen, dass Sie wegen zu weniger Elemente in der @array nicht fortgesetzt werden kann:

class Calculator 
    def initialize(array) 
    raise 'Not Enough Elements' if array.length < 2 

    @array = array 
    end 
end 
1

Hier ist eine mögliche Struktur:

module Validator 
    [:add, :substract, :multiply, :divide].each do |method| 
    define_method(method) do 
     validate_array_length(2) 
     super() 
    end 
    end 

    private 

    def validate_array_length(min,max=min) 
    raise 'Not Enough Elements' if @array.length < min 
    raise 'Too Many Elements' if @array.length > max 
    end 
end 

class Calculator 
    prepend Validator 
    def initialize(*values) 
    @array = values 
    end 

    def add 
    @array << @array.pop + @array.pop 
    end 

    # def substract .... 
end 

c = Calculator.new(3,2) 
c.add 
c.add 
# => calculator.rb:12:in `validate_array_length': Not Enough Elements (RuntimeError) 
1
class Calculator 
    def initialize(arr) 
    @arr = arr 
    end 

    def add;  binary(:+); end 
    def subtract; binary(:-); end 
    def multiply; binary(:*); end 
    def divide; binary(:/); end 
    def power; binary(:**); end 
    def modulo; binary(:%); end 
    # ... (others) 

    def negate; unary(:[email protected]); end 
    def odd?;  unary(:odd?); end 
    def even?; unary(:even?); end 
    def to_f;  unary(:to_f); end 
    # ... (others) 

    private 

    def binary(op) 
    raise ArgumentError, 'Too few elements' if @arr.length < 2 
    @arr.pop.send(op, @arr.pop) 
    end 

    def unary(op) 
    raise ArgumentError, 'Too few elements' if @arr.length.zero? 
    @arr.pop.send(op) 
    end 
end 

#      add neg mod pow div mult  sub  add 
calc = Calculator.new [ 1, 5, 2,3, 4,5, 6,7, 8,9, 10,11, 12,13] 
    #=> #<Calculator:0x007fa192030968 @arr=[1, 5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]> 

calc.add  #=> 25 (13+12) 
calc.subtract #=> 1 (11-10) 
calc.multiply #=> 72 (8*9) 
calc.divide #=> 1 (7/6) 
calc.power  #=> 625 (5**4) 
calc.modulo #=> 1 (3%2) 
calc.negate #=> -5 (5) 
calc.add  #=> ArgumentError: Too few elements 

Es scheint, dass Sie ein RPN-Rechner bauen. Wenn dies der Fall ist, möchten Sie wahrscheinlich das Ergebnis jeder Berechnung zurück auf den Stapel schieben. Für binäre Operatoren können Sie die Methode ändern binary wie folgt:

def binary(op) 
    raise ArgumentError, 'Too few elements' if @arr.length < 2 
    @arr << @arr.pop.send(op, @arr.pop) 
    @arr[-1] 
    end 

@arr[-1], das Ergebnis der Berechnung ist der Rückgabewert. Die Modifikation von unary ist ähnlich.

Vielleicht möchten einige Stapelmanipulationsmethoden wie

def pop 
    @arr.pop 
end 

def push(n) 
    @arr << n 
end 

def swap 
    @arr[-1], @arr[-2] = @arr[-2], @arr[-1] 
end 

def rotate 
    @arr.rotate 
end 

schließlich hinzuzufügen, können Sie es finden, es klarer den Anfang zu machen (statt Ende) @arr die Spitze des Stapels, in denen Sie würden unshift/shift statt push/pop verwenden.

Verwandte Themen